Your seqCombinations almost correct, but you did not translate it from the lists in the sequence correctly. The equivalent [[]] not Seq.empty , but Seq.singleton Seq.empty :
let seqCombinations xs = Seq.fold (fun acc x -> Seq.collect (fun ys -> seq { yield ys yield seq { yield x yield! ys} }) acc) (Seq.singleton Seq.empty) xs
The above code works for finite sequences. But for the infinite, he does not work, because he first tries to reach the end, which he obviously never does for infinite sequences.
If you need a function that will work with infinite sequences, I managed to figure out two ways, but none of them are particularly pleasant. One of them uses mutable state:
let seqCombinations xs = let combs = ref [[]] seq { yield! !combs for x in xs do let added = List.map (fun ys -> x::ys) !combs yield! added combs := !combs @ added }
Otherwise, the details of seq<T> are too much:
open System.Collections.Generic let seqCombinations (xs : seq<_>) = let rec combs acc (e : IEnumerator<_>) = seq { if (e.MoveNext()) then let added = List.map (fun ys -> (e.Current)::ys) acc yield! added yield! combs (acc @ added) e } use enumerator = xs.GetEnumerator() seq { yield [] yield! combs [[]] enumerator }
I think it would be much easier if you could handle endless sequences in the form of head and tail, for example, end lists in F # or any sequence in Haskell. But of course, maybe there is a good way to express this in F #, and I just did not find it.
source share