1

我目前正在尝试学习 F# 以获得乐趣。

在 C# 中,我处理来自数据库的复杂数据,这些数据通常必须在一个元素中包含整数、双精度、字符串。这System.Collections.Generic List<T>是完美的。

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

谢谢。

我将对其进行编辑以使其更清晰:

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

4

4 回答 4

3

在回答如何使用 List 之前,您可能需要确定为什么要使用List

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

这个序列的一般功能概念可以在数组、列表、集合、字典、地图等类型中看到......任何可以枚举的东西

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

  • Set本身是无序的,但可以枚举,即使它不是第一次使用
  • List是一种结构,其中每个元素都有一个指向下一个元素的指针,允许扫描和 o(n) 随机访问。在 F# 中它是不可变的,您只能创建新的,而不能向其添加元素。你可以有 1 路遍历的链表和 2 路遍历的双链表。

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

  • 字典就像一个数组,但由某个不是整数的键索引
  • ResizableArray类似于您所知道的 c# List,因为您可以在其中添加元素

List 本身的一切都在这里

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

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

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

于 2012-09-18T15:42:54.117 回答
3

我没有投反对票,但如果没有更多细节,很难回答你的问题。

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

一旦习惯了 F# 列表,就可以使用高阶函数和列表推导来创建新列表。在您的情况下,可以按如下方式生成随机数列表:

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() ]

我不熟悉蒙特卡罗模拟;但是通读这篇文章List.map,一旦生成了随机数列表,您将在列表元素上统一应用多个函数。出于并行性目的,我建议您使用 Array 而不是 List,这样可以提供更好的加速。数组允许对元素进行随机访问,因此不同的线程可以轻松地并行访问数组的不相交部分。尽管数组是可变的,但由于高阶函数和数组理解,您可以以无副作用的方式使用它们。

为了使每个元素的任务有意义,您应该将一系列合并Array.map为一个并更改Array.mapArray.Parallel.map并行性。您还可以并行化mean功能;但是,它不太可能给您任何加速。看看这个片段,看看解决方案在数组中的样子。

更新

创建记录列表:

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

你可以对classes做类似的事情。

于 2012-09-17T20:59:43.497 回答
1

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

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

以下问题很好地描述了它:F# 是否提供自动并行性?

当然这是一般情况,因为我们不知道您的问题的细节。

于 2012-09-17T10:14:48.540 回答
1

你可以看看

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

或者

http://msdn.microsoft.com/en-us/library/dd233224.aspx

于 2012-09-17T04:30:10.693 回答