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...
- Looking at the patterns on lines 2 and 4 they seem mutually exclusive but i'm obviously missing something fundamental here
- Why would switching the patterns on lines 2 and 3 cause the compilation error to go away.