Modified map2 (without truncation of lists) in F# - how to do it idiomatically?

Posted by Maciej Piechotka on Stack Overflow See other posts from Stack Overflow or by Maciej Piechotka
Published on 2010-05-15T08:31:29Z Indexed on 2010/05/15 8:34 UTC
Read the original article Hit count: 216

Filed under:
|
|

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.

© Stack Overflow or respective owner

Related posts about F#

Related posts about haskell