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

时间:2016-01-19 21:11:18

标签: f#

我正在fsharpforfunandprofit网站上阅读Choosing between collection functions,他展示了一个例子,说明在处理完资源后如何避免访问一次性资源(第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
  }

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

let readCustomers() =
  use conn = dbConnection()
  let results = readCustomersFromDb conn 2
  results |> List.ofSeq

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

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

  results |> Seq.toList

......它的工作原理相同。

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

1 个答案:

答案 0 :(得分:10)

List.ofSeqSeq.toList都有'a seq -> 'a list类型,List.ofSeq确实定义为

let ofSeq source = Seq.toList source

(在Microsoft.FSharp.Collections.List module中定义)

所以他们确实是一样的。

当你得到一个列表(与seq不同 - 是F#中的严格结构)时,将评估序列的所有元素以填充内存中的列表 - 这就是为什么你可以使用这两个函数都强制迭代所有值。