I'm currently learning Haskell, and I am stuck with the following conundrum. What is wrong with the following construction?:
zip [1,2,3] [4,5,6]
Result: [(1,4),(2,5),(3,6)]
zipWith (+) [1,2,3] [4,5,6]
Result: [5,7,9]
zipWith (zip) [1,2,3] [4,5,6]
OR
zipWith zip [1,2,3] [4,5,6]
Result: <interactive>:22:1: error:
• No instance for (Num [()]) arising from a use of ‘it’
• In the first argument of ‘print’, namely ‘it’
In a stmt of an interactive GHCi command: print it
Expected Result: [(1,4),(2,5),(3,6)]
What am I missing?
in short: zip
is applied to the elements of the lists, not the entire lists.
zip
is not a sensical function to combine two elements that are not lists. Indeed, zip
has type zip :: [a] -> [b] -> [(a, b)]
[Hackage]. It thus takes two lists and creates 2-tuples with these lists.
This means that zipWith
will work with zip
as function if we have a list of lists:
zipWith zip [[1],[2,3]] [[4],[5, 6]] -- [[(1,4)], [(2, 5), (3, 6)]]
here the outer zipWith
thus zips the outer structures, and zip
will be called on zip [1] [4]
and zip [2, 3] [5, 6]
to produce [(1, 4)]
and [(2, 5), (3, 6)]
respectively.
zip
is a shortcut for:
zip = zipWith (,)
indeed, (,) :: a -> b -> (a, b)
is a data constructor, and therefore also a function that takes two elements, and produces a 2-tuple of these two elements, so:
zipWith (,) [1, 2, 3] [4, 5, 6] -- [(1, 4), (2, 5), (3, 6)]
will zip the two lists together.