首页 文章

F#不可变版本的List <T>?

提问于
浏览
0

我现在正试图学习F#的乐趣 .

在C#中,我处理来自数据库的复杂数据,这些数据通常必须包含一个元素中的整数,双精度数,字符串 . System.Collections.Generic List<T> 非常适合这种情况 .

我正在尝试在F#中探索并行性,但需要一个不可变的 List<T> 来这样做 . 这可能吗?语法是否类似于C# var x = new List<T>

谢谢 .

我要编辑它以使其更清晰:

在F#中,我想创建一个不可变的类或记录列表(应该命名),就像我在C#中使用List一样 . 这样我就可以使用相同元素中的分组字符串,整数,双精度数 . 希望这很简单 .

4 回答

  • 0

    我没有投票,但没有更多细节,很难回答你的问题 .

    在F#中,不可变列表是最常用的数据结构 . 您经常使用cons构造函数 (::) 和空列表 [] 构造列表 . 例如, [1; 2; 3]1::2::3::[] 的语法糖 . 您可以按照@Brian建议的链接阅读有关基本列表处理的更多信息 .

    一旦习惯了F#list,就可以使用high-order functions和list comprehension来创建新列表 . 在您的情况下,可以生成随机数列表,如下所示:

    let genRand =
        let rand = System.Random()
        fun () -> rand.NextDouble()
    
    /// Creating a list using high-order functions
    let genRandList n = List.init n (fun _ -> genRand())
    
    /// Creating a list using list comprehension
    let genRandList' n = [ for i in 1..n -> genRand() ]
    

    我不熟悉蒙特卡罗模拟;但是通过this article读取,一旦生成随机数列表,就会在列表元素上统一应用几个 List.map 函数 . 出于并行目的,我建议您使用Array而不是List,这样可以提供更好的加速 . 数组允许对元素进行随机访问,因此不同的线程可以轻松地并行访问数组的不相交部分 . 虽然数组是可变的,但是由于high-order functions和数组理解,你可以以无副作用的方式使用它们 .

    为了使每个元素的任务都很重要,您应该将一系列 Array.map 合并为一个,并将 Array.map 更改为Array.Parallel.map以实现并行性 . 你也可以并行化 mean 函数;但是,它不太可能给你任何加速 . 看一下this snippet,了解解决方案与数组的关系 .

    UPDATE

    创建记录列表:

    type RandPair = { First: float; Second: float}
    let genRandPairs n = [ for i in 1..n -> 
                              { First = genRand(); Second = genRand() } ]
    

    您可以为classes做类似的事情 .

  • 0

    在回答如何使用List之前,您可能需要确保 why 您想要使用 List .

    这不是微不足道的,因为我们在计算机科学中称之为 List 是一个非常精确的结构,其意义不同于 sequence ,这更多地与'list'的随意使用相对应 . 在C#中,这称为IEnumerable,在F#中是别名seq(它们是相同的BCL类型) .

    这个序列的一般功能概念可以在类型中看到,如数组,列表,集合,字典, Map 等......可以枚举的任何内容

    为了让您了解不同的结构,这里是动物学的示例列表(错误序列):

    • Set 本身是无序的,但即使它不是第一次使用也可以枚举

    • List 是一种结构,其中每个元素都有一个指向下一个元素的指针,允许扫描和o(n)随机访问 . 在F#中它是不可变的,你只能创建新的,而不是添加元素 . 您可以使用链接列表进行单向遍历,使用双向链接列表进行双向遍历 .

    • Array 是一个连续的内存块,允许o(1)随机访问,如果您事先知道集合的大小,那就太好了

    • Dictionary 就像一个数组,但是由一些不是整数的键索引

    • ResizableArray 类似于你知道的c#List,你可以在其中添加元素

    列表本身的一切都在这里

    http://en.wikibooks.org/wiki/F_Sharp_Programming/Lists

    如果你了解你的程序,你应该能够事先证明为什么你使用这个结构而不是另一个 .

    如果你的程序有一天太慢,那么去找看它们是o(n)的结构上的'find' . 也就是说,相当于数据库中的“全扫描” . 获得正确的结构将使您的程序飞起来

  • 2

    我认为,在这个问题的上下文中,应该说F#immutable结构对你没有多大帮助,因为如果你创建其他答案中描述的不可变F#列表,你只能确定你的列表是没有修改,而它所持有的引用可能指向不是的对象不可改变的 .

    也就是说,即使它们是这样,并行化也不会自动发生 . F#不是纯语言,所以不能确定你的对象引入了什么样的副作用,并且不能自己并行化任何东西(即使它可能,它可能不是非常有效的解决方案,因为自动并行化是不那么容易) .

    以下问题很好地描述了它:Does F# provide you automatic parallelism?

    当然,这一切都很普遍,因为我们不知道你的问题的细节 .

相关问题