gusty / FsControl

[ARCHIVED] FsControl in now included in FSharpPlus https://fsprojects.github.io/FSharpPlus
Apache License 2.0
105 stars 16 forks source link

Unzip for seq. #69

Closed gusty closed 7 years ago

gusty commented 7 years ago

The problem with unzip for seqs as in many other seq functions is the decision to make it strict which would not work for infinite sequences or make it lazy and allow to iterete twice the sequences. It worth exploring a lazy implementation which caches the iteration as it goes.

gusty commented 7 years ago

The lazy implementation would look like:

let unzip x =
    let c = Seq.cache x
    Seq.map fst c, Seq.map snd c

The resulting sequence will be always cached, even if the first resulting sequence is iterated twice, it will traverse the sequence only once.

This might be undesirable in some cases.

The other alternative is to allow to traverse the sequence many times. Although this alternative is only suitable for restartable sequences, has the advantage that is always possible to transform it to the first alternative just by calling Seq.cache.

The same logic applies for existing functions in the core library, like Seq.tail.

let s = Seq.initInfinite (fun i -> i, i)
let unzip x =
    Seq.map fst x, Seq.map snd x

let unzipped = unzip s
let cachedUnzipped = s |> Seq.cache |> unzip

It worths noting that both results will work with infinite sequences:

let x = fst unzipped |> Seq.take 10 |> Seq.toList
let y = fst cachedUnzipped |> Seq.take 10 |> Seq.toList