Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between Seq.toList and List.ofSeq?

Tags:

f#

I was reading Choosing between collection functions on the fsharpforfunandprofit site, and he showed an example of how to avoid accessing a disposable resource after it had been disposed (Section 28, right at the end of the article).

He simulated a database with the following...

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
  }

...and then showed how to avoid the problem by enumerating the sequence before returning it...

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

I was a bit confused by that last bit, as I thought we had a sequence, and wanted to convert it to a list. This is how it works in C#, which could be where I'm thinking wrongly. He seems to be taking a list and converting it to a sequence.

Anyway, I tried changing that last line to...

  results |> Seq.toList

...and it worked just the same.

So, what's the difference between the two, and why do they do the same thing here? I thought sequences were non-enumerated, in which case I would have expected his original code not to have worked.

like image 337
Avrohom Yisroel Avatar asked Dec 10 '22 18:12

Avrohom Yisroel


1 Answers

Both List.ofSeq and Seq.toList have type 'a seq -> 'a list and indeed List.ofSeq is defined as

let ofSeq source = Seq.toList source

(defined in the Microsoft.FSharp.Collections.List module)

so indeed they are just the same.


As you get a list (which - unlike a seq - is a strict structure in F#) all the elements of the sequence are evaluated to populate the list in memory - that's why you can use both functions to force the iteration of all the values.

like image 58
Random Dev Avatar answered Dec 29 '22 17:12

Random Dev