F#列表是否持久?

Meh*_*ran 3 performance f# immutability persistent

我是F#的C#开发人员,我知道在.net中字符串是不可变的。换句话说,每次修改字符串时,都会得到一个新的字符串实例。

对于像我这样的非功能性头脑,第一个问题将是效率,而且我了解C#可变对象不是持久性的。因为在大多数应用程序中字符串操作通常都很简单。

我的问题是,F#列表也是这种情况吗?F#是否会在更改时克隆每个列表?例如,当过滤列表时,我是否会创建一个包含较少项目的新列表?

更新:我没有比较.net字符串和列表。我将字符串命名为一个不可变对象的示例,并且想知道F#是否为其List提供任何特殊处理。

这就是我所说的“ 持久 ”。

Dan*_*mov 5

我认为Dustin Campbell的介绍在解释列表不变性方面做得非常出色。

在功能世界中,列表是不可变的。这意味着可以共享节点,因为原始列表永远不会改变。因为第一个列表以空列表结尾,所以必须复制其节点才能将其最后一个节点指向第二个列表。追加操作后,我们的列表如下所示:

在此处输入图片说明

在这一点上,您当中更持怀疑态度的人可能会说:“嗯,这是一个非常有趣的理论,但是您能证明吗?”

没问题。

使用F#列表是递归的知识,我们可以通过合并尾部,尾部和尾部来检索组合的后半部分(内部列表从4开始)。List.tl是F#提供的用于提取列表尾部的函数。

> let lastHalf = List.tl (List.tl (List.tl combined));;

val lastHalf : int list

> lastHalf;;

val it : int list = [4; 5; 6]
Run Code Online (Sandbox Code Playgroud)

最后,由于F#是.NET Framework的一等公民,因此我们可以完全访问所有基类库。因此,我们可以使用该Object.ReferenceEquals方法测试lastHalf和second是否确实是同一实例。

> System.Object.ReferenceEquals(lastHalf, second);;

val it : bool = true
Run Code Online (Sandbox Code Playgroud)

那里有它。信不信由你,与必须添加可变列表相比,添加两个不可变列表实际上可以比添加可变列表更快,内存效率更高。