I wanna check if boolean elements in a list are all True, all False, or both True and False. Here is my code for now:
data Answer3 = Just_True | Just_False | Both deriving (Eq, Ord, Show) type A3 = Answer3 checkBoolean :: [Bool] -> A3 checkBoolean (x:x1:xs) = if (length (x:x1:xs) `mod` 2) == 0 then if (x && x1) && checkBoolean'(x1:xs)== True then Just_True else if (x && x1) == True then Both else if checkBoolean'(xs)== True then Both else Just_False else if x && checkBoolean'(x1:xs) == True then Just_True else if x == False then Just_False else Both checkBoolean':: [Bool] -> Bool checkBoolean' (x:xs) = x && (checkBoolean'(xs)) checkBoolean'  = True
*Main> checkBoolean [False, False, False] Just_False
*Main> checkBoolean [True, True, True] Just_True
*Main> checkBoolean [True, False, False] Both
gives correct result. But
*Main> checkBoolean [False, False, True, False, True] Just_False
*Main> checkBoolean [False, False, True] Just_False
do not work as I intended.
[False, False, True, False, True] is Both, and
[False, False, True] is also Both
I know I didn't think all possible cases and thats why this doesn't work, but is there an efficient way to write this without writing this much if else statements?
Oh wow, you kinda overcomplicated it.
There's a very useful function called
all :: (a -> Bool) -> [a] -> Bool
It checks all elements for a predicate, which for booleans could be just a pair of
not functions, but you can also explicitly check equality to a value, which makes for pretty readable code:
checkBoolean xs = if all (== True) xs then Just_True else if all (== False) xs then Just_False else Both
It's probably also a good idea to be somewhat more explicit about the empty list (
) case. Should it be
Both, or perhaps another value altogether?