9

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?

TrebledJ
  • 8,713
  • 7
  • 26
  • 48
Glove
  • 960
  • 6
  • 17
  • 30

1 Answers1

12

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)
Don Stewart
  • 137,316
  • 36
  • 365
  • 468
  • is there a difference between using ':' and '++' ? – Glove Apr 25 '11 at 08:00
  • 1
    Yes, `(++)` is list append, and traverses its first argument, while `(:)` is O(1), and prepends its argument to the list. – Don Stewart Apr 25 '11 at 08:02
  • 1
    @biz, and there's the subtle, but important, difference that `:` is a data constructor, while `++` is just an ordinary function. That means you can use `:` when pattern matching, but you can't use `++`. Take a look in ghci with `:i (:)` and `:i (++)`. – Ionuț G. Stan Apr 25 '11 at 08:54
  • 3
    In this case, however, there should be no difference between using `(a,b) : ...` and `[(a,b)] ++ ...`. The former is simpler and more idiomatic, but the semantics and performance should be identical (the compiler will just unfold the latter to the former) – luqui Apr 25 '11 at 09:20
  • 3
    This answer implements zip, but does not critique the asker's version or explain why it is implemented the way it is. Could be better. – luqui Apr 25 '11 at 09:20
  • Agreed. Perhaps we could link to the general answers on `(++)` and `(:)` – Don Stewart Apr 25 '11 at 14:33
  • 1
    By the way, GHC does literally optimize them both to the same code, thanks to `build/foldr` rules. – Don Stewart Apr 26 '11 at 03:19
  • 'f a b' ?? don't get it – Qbik Jan 04 '19 at 06:39