Checking if all bolean elements in a list are the same in Haskell

  • A+

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:

all :: (a -> Bool) -> [a] -> Bool 

It checks all elements for a predicate, which for booleans could be just a pair of id and 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 Just_True, Just_False, Both, or perhaps another value altogether?


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: