Closed gusty closed 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
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.