I am writing a function majority.
The function returns True if at least two of the parameters are True.
The function returns False if at least two of the parameters are False.
The function can be written like this:
majority :: (Bool,Bool,Bool) -> Bool
majority (True,True,_)=True
majority (True,_,True) = True
majority (_,True,True)=True
majority _ = False
Alternatively, a list comprehension can be used:
majority' (x,y,z) = length [b | b <- [x,y,z] , b] >= 2
I don't fully understand why this second solution works.
I know that this means we will take b such that it is one of [x,y,z] and b applied to b must be True. The length of this list must be greater than or equal to 2.
Does the b in the predicate (the third b) change its value for that it is equal to x, then y and then z. Or, does b always have the value of x?
I tried:
majority'' (x,y,z) = length [b | b <- [x,y,z] , True] >= 2
I found that this always returned True,even when the function should return False.
Also, I noticed that
[b | b <- [False,True,True] , True] would return [False,True,True]
And in general,
[b | b <- [x,y,z] , True] would return [x,y,z]
However,
[b | b <- [False,True,True] , b] would return [True,True]
And in general,
[b | b <- [x,y,z] , b] would return a list of Trues which is as long as the number of Trues in [x,y,z]
This explains why
majority'' (x,y,z) = length [b | b <- [x,y,z] , True] >= 2
always returns True. The inequality is always True, because the list [b | b <- [x,y,z],True] always has a length of 3.
Why does using b as the predicate work in?
majority' (x,y,z) = length [b | b <- [x,y,z] , b] >= 2