在F#中如何实现列表?

在F#中如何实现列表?,f#,F#,我很好奇列表模块/类型在F#中是如何工作的,特别是它是否对此进行了优化 let xs = ["1"; "2"; "3"] let ys = "0"::xs let zs = ["hello"; "world"]@xs 我已经看过了一些相关的资料来源 我想知道制作ys时是否复制了xs 我认为如果你只使用cons元素,就很容易指向现有的列表 如果要连接,我想这可能是不可能的,因为它需要改变列表的最后一个元素以指向下一个 如果有人能够注释/粘贴来自FSharp.Core的代码片段,那将是理想的。

我很好奇列表模块/类型在F#中是如何工作的,特别是它是否对此进行了优化

let xs = ["1"; "2"; "3"]

let ys = "0"::xs

let zs = ["hello"; "world"]@xs
我已经看过了一些相关的资料来源

我想知道制作
ys
时是否复制了
xs

我认为如果你只使用cons元素,就很容易指向现有的列表

如果要连接,我想这可能是不可能的,因为它需要改变列表的最后一个元素以指向下一个


如果有人能够注释/粘贴来自FSharp.Core的代码片段,那将是理想的。

所以列表的实现有点奇怪。它实际上是作为一个受歧视的联盟实施的。根据规范:

type 'T list =
| ([])  
| (::)  of 'T * 'T list 
因此,您可以将
看作一个函数,它接受两个参数并创建一个元组(速度很快,因为它与列表大小无关)

@
要复杂得多。以下是实施方案:

    let (@) l1 l2 = 
        match l1 with
        | [] -> l2
        | (h::t) -> 
        match l2 with
        | [] -> l1
        | _ -> 
          let res = [h] 
          let lastCons = PrivateListHelpers.appendToFreshConsTail res t 
          PrivateListHelpers.setFreshConsTail lastCons l2;
          res

这两个奇怪的函数基本上改变了列表
appendToFreshConsTail
复制列表并返回最后一个元素
setFreshConsTail
然后更改最后一个元素,使其下一个元素设置为
l2
,而不是
[]
加入列表。

创建
ys
xs
时不会深度复制(这是不可变单链接列表的优点之一)你知道我在哪里可以找到关于F#的信息吗?最后一段就是我要找的!谢谢!