Search code examples
haskellfunctional-programmingfoldcombinators

Implement zip using foldr


I'm currently on chapter 4 of Real World Haskell, and I'm trying to wrap my head around implementing foldl in terms of foldr.

(Here's their code:)

myFoldl :: (a -> b -> a) -> a -> [b] -> a

myFoldl f z xs = foldr step id xs z
    where step x g a = g (f a x)

I thought I'd try to implement zip using the same technique, but I don't seem to be making any progress. Is it even possible?


Solution

  • zip2 xs ys = foldr step done xs ys
      where done ys = []
            step x zipsfn []     = []
            step x zipsfn (y:ys) = (x, y) : (zipsfn ys)
    

    How this works: (foldr step done xs) returns a function that consumes ys; so we go down the xs list building up a nested composition of functions that will each be applied to the corresponding part of ys.

    How to come up with it: I started with the general idea (from similar examples seen before), wrote

    zip2 xs ys = foldr step done xs ys
    

    then filled in each of the following lines in turn with what it had to be to make the types and values come out right. It was easiest to consider the simplest cases first before the harder ones.

    The first line could be written more simply as

    zip2 = foldr step done
    

    as mattiast showed.