Is there a better way to re-create this function? It compiles fine.
This is what I have:
zip3' :: [a] -> [b] -> [c] -> [(a,b,c)]
zip3' [] _ _ = []
zip3' _ [] _ = []
zip3' _ _ [] = []
zip3' (a:as) (b:bs) (c:cs) = (a,b,c) : zip3' as bs cs
I'm just wondering if there is a better way to summarize this:
zip3' [] _ _ = []
zip3' _ [] _ = []
zip3' _ _ [] = []
It works fine. If you want to make the program shorter, you can write:
zip3' :: [a] -> [b] -> [c] -> [(a,b,c)]
zip3' (a:as) (b:bs) (c:cs) = (a,b,c) : zip3' as bs cs
zip3' _ _ _ = []
Since the first line will only fail to fire if there is at least one of the three lists that is not (_:_)
(so []
). But this is sometimes seen as an anti-pattern, since in a very unlike event that one adds a constructor to the list data type, this might end up with an empty list (whereas in that case, we perhaps better get an error). I agree that for lists this is close to impossible: a lot of libraries and programs would no longer work. But in general it is not uncommon that you for instance design a data type, and later change your mind and add an extra constructor.
If we inspect the source code of zip3 :: [a] -> [b] -> [c] -> [(a,b,c)]
, then we see it is implemented that way [source]:
zip3 :: [a] -> [b] -> [c] -> [(a,b,c)] -- Specification -- zip3 = zipWith3 (,,) zip3 (a:as) (b:bs) (c:cs) = (a,b,c) : zip3 as bs cs zip3 _ _ _ = []
For some reason zip
itself is implemented in the "question" style [source]:
zip :: [a] -> [b] -> [(a,b)] zip [] _bs = [] zip _as [] = [] zip (a:as) (b:bs) = (a,b) : zip as bs
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