Booleans in Lists

As announced last week, this year we'll be doing short form articles twice a week highlighting useful library functions. The focus area for the month of January is simple list functions. We'll start with some simple functions that interact with booleans.

Like any other language, Haskell has operators for dealing with booleans like "and" and "or":

(&&) :: Bool -> Bool -> Bool

(||) :: Bool -> Bool -> Bool

But these only work with two booleans. If you have a variable-sized list of items, you can't directly apply these operators. In a language like Java, you'd write a for loop to deal with this. Here's how you would take "or" over a whole list.

boolean[] myBools;
result = false;
for (boolean b : myBools) {
  result |= b;
}

In Haskell, you'd write a recursive helper instead. But you get this for free with the and and or functions:

and :: [Bool] -> Bool

or :: [Bool] -> Bool

Here's how it might look in GHCI:

>> and [True, True, True]
True
>> and [True, False, True]
False
>> or [True, False, True]
True
>> or [False, False, False]
False

Most of the time though, you won't just be dealing with booleans. You'll have a list of other objects, and you'll want to ask a question like, "Do these all satisfy some condition?" If you can express that condition with a predicate function, you can check that condition for all items in the list using any and all. The first is like "or", the second is like "and".

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

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

Here they are in action with numbers:

>> any (\i -> i `mod` 2 == 0) [2, 4, 7, 8]
True
>> all (\i -> i `mod` 2 == 0) [2, 4, 7, 8]
False

These functions are equivalent to mapping the predicate and then using one of our earlier functions:

>> or (map (\i -> i `mod` 2 == 0) [2, 4, 7, 8])
True
>> all (map (\i -> i `mod` 2 == 0) [2, 4, 7, 8])
True

Finally, these functions aren't just for lists. They generalize to any foldable type:

and :: (Foldable t) => t Bool -> Bool

or :: (Foldable t) => t Bool -> Bool

any :: (Foldable t) => (a -> Bool) -> t a -> Bool

all :: (Foldable t) => (a -> Bool) -> t a -> Bool

...

>> and (Set.fromList [True, False])
False

Be sure to subscribe to our newsletter so you can stay up to date with the latest news! Subscribing will give you access to all our subscriber resources, including our Beginners Checklist!

Previous
Previous

In the Middle: Intersperse and Intercalate

Next
Next

New in ‘22!