For learning purposes I am trying to write my own implementation of the zipWith
function. However, I am hitting an issue with pattern matching on edge cases with _
. First I will describe the good case, then the bad case. Hopefully someone will be able to explain why they behave differently. Thanks
If I write the zipWith
function as follows, it works (Note the order of the edge cases matching empty list on lines 2 & 3):-
zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
zipwith' _ [] _ = []
zipWith' _ _ [] = []
zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys
Compiling in GHCI:-
ghci> :l ZipWith.hs
[1 of 1] Compiling Main ( ZipWith.hs, interpreted )
Ok, the above is fine, yet if I swap the pattern matching for the edge cases around GHCI throws 'Multiple declarations of' error for lines 2 and 4.
zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith' _ _ [] = []
zipwith' _ [] _ = []
zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys
Compiling in GHCI:-
ZipWith.hs:4:0:
Multiple declarations of `Main.zipWith''
Declared at: ZipWith.hs:2:0
ZipWith.hs:4:0
Failed, modules loaded: none.
I'm stumped...
The error message isn't complaining about overlapping patterns (your patterns do overlap in the case of two empty lists, but that's neither the problem, nor a problem), but multiple definitions of the zipWith
function.
The reason for that is that in your second case you have one definition of zipWith
followed by an unrelated definition of zipwith
(note the lower case w
), followed by a new, conflicting definition of zipWith
. In other words it's a simple typo. (Did take me a while to see though - quite a sneaky typo)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With