Seq.toList和List.ofSeq有什么区别?

Avr*_*oel 2 f#

我正在阅读fsharpforfunandprofit网站上的收集功能之间的选择,他展示了一个例子,说明如何在处理后丢失访问一次性资源(第28节,正好在文章末尾).

他用以下方法模拟了一个数据库......

let dbConnection() =
  printfn "Opening connection"
  { new System.IDisposable with
    member this.Dispose() =
      printfn "Disposing connection"
  }

// Read some records from the database
let readCustomersFromDb conn n =
  let makeCustomer i =
    sprintf "Customer %d" i
  seq {
    for i = 1 to n do
      let customer = makeCustomer i
      printfn "Loading %s from the database" customer
      yield customer
  }
Run Code Online (Sandbox Code Playgroud)

...然后展示如何通过在返回之前枚举序列来避免问题...

let readCustomers() =
  use conn = dbConnection()
  let results = readCustomersFromDb conn 2
  results |> List.ofSeq
Run Code Online (Sandbox Code Playgroud)

最后一点我感到有些困惑,因为我认为我们有一个序列,并希望将其转换为列表.这就是它在C#中的工作方式,这可能是我错误思考的地方.他似乎正在列出一个列表并将其转换为序列.

无论如何,我尝试将最后一行改为......

  results |> Seq.toList
Run Code Online (Sandbox Code Playgroud)

......它的工作原理是一样的.

那么,两者之间有什么区别,为什么他们在这里做同样的事情呢?我认为序列是非枚举的,在这种情况下我会期望他的原始代码不起作用.

Car*_*ten 11

无论List.ofSeqSeq.toList有型'a seq -> 'a list而且确实List.ofSeq被定义为

let ofSeq source = Seq.toList source
Run Code Online (Sandbox Code Playgroud)

(在Microsoft.FSharp.Collections.List模块中定义)

所以他们确实是一样的.


当你一个列表( -不像seq-在F#中严格的结构)的序列中的所有元素进行评估,以填充内存中的列表-这就是为什么你可以使用这两个功能,迫使所有的值迭代.