zip function in Haskell

Glove picture Glove · Apr 25, 2011 · Viewed 16.7k times · Source

implementation of a zip function that takes two lists as parameters and returns a new list of pairs. I got this so far

myZip [] [] = []
myZip (x:xs) (y:ys) = [(x,y)] ++ myZip xs ys

any help?

Answer

Don Stewart picture Don Stewart · Apr 25, 2011

There's really only one way to write it for lists, even for homework:

zip :: [a] -> [b] -> [(a,b)]
zip (a:as) (b:bs) = (a,b) : zip as bs
zip _      _      = []

or, more generally,

zipWith :: (a -> b -> c) -> [a]->[b]->[c]
zipWith f (a:as) (b:bs) = f a b : zipWith f as bs
zipWith _ _      _      = []

If you want to get wacky, and play with stream fusion, the version from the stream fusion paper, in automaton style,

zipWith :: (a -> b -> c) -> Stream a -> Stream b -> Stream c
zipWith f (Stream next0 sa0) (Stream next1 sb0) = Stream next (sa0, sb0, Nothing)
  where
    next (sa, sb, Nothing) = case next0 sa of
        Done        -> Done
        Skip    sa' -> Skip (sa', sb, Nothing)
        Yield a sa' -> Skip (sa', sb, Just a)

    next (sa', sb, Just a) = case next1 sb of
        Done        -> Done
        Skip    sb' -> Skip          (sa', sb', Just a)
        Yield b sb' -> Yield (f a b) (sa', sb', Nothing)