I'd like to rewrite such function into F#:
zipWith' :: (a -> b -> c) -> (a -> c) -> (b -> c) -> [a] -> [b] -> [c]
zipWith' _ _ h [] bs = h `map` bs
zipWith' _ g _ as [] = g `map` as
zipWith' f g h (a:as) (b:bs) = f a b:zipWith f g h as bs
My first attempt was:
let inline private map2' (xs : seq<'T>) (ys : seq<'U>) (f : 'T -> 'U -> 'S) (g : 'T -> 'S) (h : 'U -> 'S) =
let xenum = xs.GetEnumerator()
let yenum = ys.GetEnumerator()
seq {
let rec rest (zenum : IEnumerator<'A>) (i : 'A -> 'S) =
seq {
yield i(zenum.Current)
if zenum.MoveNext() then yield! (rest zenum i) else zenum.Dispose()
}
let rec merge () =
seq {
if xenum.MoveNext()
then
if yenum.MoveNext()
then yield (f xenum.Current yenum.Current); yield! (merge ())
else yenum.Dispose(); yield! (rest xenum g)
else
xenum.Dispose()
if yenum.MoveNext()
then yield! (rest yenum h)
else yenum.Dispose()
}
yield! (merge ())
}
However it can hardly be considered idiomatic. I heard about LazyList
but I cannot find it anywhere.