Reputation: 81
For part of a homework assignment in a beginner Haskell course, I'm trying to write a program that will take a list of pairs of Bools, and returns a list of Bools coming from the pairs of bools with an "&&" between them. For example...
andandbool [(True,True),(True,False),(False,True),(False,False)]
would return:
[True, False, False, False]
I keep running into trouble, however. My code looks like this.
andandbool :: [(Bool,Bool)] -> [Bool]
andandbool [a] = [fst x && snd x | x <- [a]]
It works fine when I provide a list of only one pair, but reports "Non-exhaustive patterns in function andandbool" when I enter a list of multiple pairs. Is there some sort of list comprehension that I'm missing? Any pointers in the right direction would be greatly appreciated.
Upvotes: 1
Views: 145
Reputation: 35089
Now that I'm at my computer I'll turn my comment into an answer.
When you name the argument of the function [a]
, Haskell interprets that as your function pattern matching on a list of one element. That's why your function only worked on one-element lists. To fix it, just rename the function argument to something without brackets in the name:
andandbool :: [(Bool,Bool)] -> [Bool]
andandbool as = [fst x && snd x | x <- as]
That as
argument will now match any list.
Edit: Like @Ankur mentioned, you can simplify this as:
andandbool as = [x && y | (x, y) <- as]
If you really want to play code golf you can simplify this even more as:
andandbool = map (uncurry (&&))
Upvotes: 5