The boolean operators && and || take boolean values as their operands. Sometimes you want to apply a boolean operator to a list of boolean values. Writing something like a && b && c && d && e can quickly become unwieldy and tedious. What you want are versions of && and || that can operate on lists, not necessarily of boolean values. Well, this is your lucky day. For a limited time only starting from now to eternity, you can use various functional versions of your favourite boolean operators. Too good to be True? Au contraire, mon ami(e).

and

The function and outputs True if all elements of a list are True, and False otherwise. It is the function counterpart of the operator &&. The function and is useful when we want to know whether all elements of a list satisfy a given property. For example, below we check whether all elements of a list are even.

1
2
3
4
5
6
ghci> and [even x | x <- [1 .. 10]]
False
ghci> and [even x | x <- [2, 4 .. 10]]
True
ghci> and [even x | x <- [1, 3 .. 10]]
False

Pietro manages a pet shop. As part of his monthly routine, Pietro checks to see whether all pets in his shop have had a health check within the last 12 months. A number of new pets were delivered to the shop recently. Pietro does not recall bringing the new pets to a veterinary clinic within the last two weeks. The following shows the pets database and the health check status of all animals in Pietro’s shop.

:include: file=”assets/src/list/pet.hs”, line=25:92

or

The function or outputs True if one element of a list is True. Like its operator counterpart ||, or outputs False if all elements are False. The function or is useful in situations where we only care that one element is True. It might be the case that multiple elements are True. However, we are only interested in whether at least one element is True.

For example, the list of integers from 1 up to and including 10 has at least one odd number. Similarly, the list [1 .. 10] has at least one even number. The following GHCi session should confirm the above observations:

1
2
3
4
ghci> or [even x | x <- [1 .. 10]]
True
ghci> or [odd x | x <- [1 .. 10]]
True

The vowels of the English alphabet are “A”, “E”, “I”, “O”, and “U”. Some words in English do not contain a vowel at all. Here are some common, and not so common, words that consist of only consonants:

C G P S T W
cry glyph ply sty thy why
crypt gym pwn sync try wry
cyst gypsy pygmy syzygy tryst wyrm

If you were to test each of the above words for vowels, the result would be False. Observe:

:include: file=”assets/src/list/word.hs”, line=25:60

all

The function all is a predicate counterpart of and. Whereas and expects all elements of a list to be boolean values, all accepts a predicate that is used to determine whether all elements of a list satisfy the predicate. For example, suppose we have a list of integers. We do not know whether all the integers are positive. The function all can help us in this scenario. Consider the GHCi session below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ghci> import Control.Monad
ghci> import System.Random.Stateful
ghci> ella <- replicateM 20 (uniformRM (-3, 20) globalStdGen :: IO Integer)
ghci> ellb <- replicateM 20 (uniformRM (-3, 20) globalStdGen :: IO Integer)
ghci> ellc <- replicateM 20 (uniformRM (1, 20) globalStdGen :: IO Integer)
ghci> ella
[1,2,15,12,1,10,17,-3,7,20,-3,3,8,8,14,19,11,-2,1,18]
ghci> all (\x -> x > 0) ella
False
ghci> ellb
[1,10,4,1,3,2,10,-1,6,4,20,0,4,-2,14,19,-3,18,16,13]
ghci> all (\x -> x > 0) ellb
False
ghci> ellc
[6,9,9,13,16,2,17,11,15,7,2,7,9,16,20,8,4,7,18,5]
ghci> all (\x -> x > 0) ellc
True

As another example, consider the table below of the goals scored by players of Arsenal during the 2022—2023 season of the Premier League. We included only male players who scored at least one goal. The header “Goals-PK” means non-penalty goals.

Player Goals Goals-PK
Ben White 2 2
Bukayo Saka 14 12
Eddie Nketiah 4 4
Fabio Vieira 1 1
Gabriel Dos Santos 3 3
Gabriel Jesus 11 10
Gabriel Martinelli 15 15
Granit Xhaka 7 7
Jakub Kiwior 1 1
Leandro Trossard 1 1
Martin Ødegaard 15 15
Oleksandr Zinchenko 1 1
Rob Holding 1 1
Reiss Nelson 3 3
Thomas Partey 3 3
William Saliba 2 2

Our question is: Were all the goals scored non-penalty? If a player scored $g$ goals and statistics says the player scored $h$ non-penalty goals, then all goals scored by the player is non-penalty provided that $g = h$. I’m too lazy to check by hand. Let’s delegate the manual work to Haskell:

:include: file=”assets/src/list/arsenal.hs”, line=25:60

any

The function any is the predicate counterpart of or. The function or requires all elements of a list to be boolean values. On the other hand, any requires a predicate based upon which the function decides whether some elements of a list satisfy the predicate.

Consider a bunch of random integers. We know that there are negative integers and zero. Is there at least one positive integer? Let’s find out.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ghci> import Control.Monad
ghci> import System.Random.Stateful
ghci> a <- replicateM 20 (uniformRM (-20, 3) globalStdGen :: IO Integer)
ghci> b <- replicateM 20 (uniformRM (-20, 2) globalStdGen :: IO Integer)
ghci> c <- replicateM 20 (uniformRM (-20, 0) globalStdGen :: IO Integer)
ghci> a
[-16,-14,-1,-16,-19,-4,-8,-19,-1,-5,-6,1,-7,-3,-8,-15,-4,-11,-17,-10]
ghci> any (\x -> x > 0) a
True
ghci> b
[2,-4,-5,-5,2,0,2,-1,-18,-14,-2,-15,-11,-20,-15,-11,0,-4,-14,-4]
ghci> any (\x -> x > 0) b
True
ghci> c
[-20,-17,-10,-1,-6,-6,-3,-4,-3,-3,-1,-8,-4,-7,-19,-14,0,-15,-1,-7]
ghci> any (\x -> x > 0) c
False

Violet wants to increase her vocabulary. The words in her list vary in length. She wants to know whether the list has a short word, i.e. a word of at most 5 letters. Learning short words all the time is no fun. Violet also wants to determine whether the list has a long word, i.e. a word of at least 8 letters. Let’s use Haskell to find out:

1
2
3
4
5
ghci> a = ["benign", "elixir", "tumid", "intemperance", "narcissist"]
ghci> any (\str -> length str <= 5) a
True
ghci> any (\str -> length str >= 8) a
True

Exercises

:exercise: Consider the script :script: file=”assets/src/list/arsenal.hs” from the section all. Modify the script to use any to determine whether any of the goals scored were a result of a penalty kick.

:exercise: Recall the script :script: file=”assets/src/list/pet.hs” from the section and. Modify the script to determine whether all birds have had a health check within the last 12 months. Furthermore, determine whether some of the birds have had a health check within the same time period.

:exercise: Many words in English that do not have a vowel use the letter “Y” to simulate a vowel sound. Refer to the script :script: file=”assets/src/list/word.hs” from the section or. Modify the script to determine whether some of the words in the word list do not use “Y”. Print such words to standard output.

:exercise: Recall the exercise on Gilbreath’s conjecture from the section Free range numbers. Let $\ell$ be a list of prime numbers not exceeding an integer $n > 1$. Successive application of the difference operation would eventually result in the list [1]. Determine how many times you must perform the difference operation in order to obtain a list that satisfies one of the properties below:

The values of $n$ are drawn from the list [10, 100, 1000, 10000, 100000].

:exercise: The Britannica Dictionary has a list of 100 core words for the TOEFL. Let’s refer to these words as the Britannica core. Use the Britannica core to answer the following questions.

  1. For each letter of the alphabet, is there a word that starts with the given letter? Output each letter for which the Britannica core does not have a word beginning with the letter.
  2. Do all words have at least two unique vowels? Output each word in the Britannica core that uses exactly one unique vowel.
  3. Are all words of at least length 5? Output each word that has length 4 or less.

:exercise: Consider the list below of female players of Sydney FC during the 2022—2023 soccer season in Australia.

:include: file=”assets/src/list/solution/sydney.hs”, line=28:69

Write a program to help you answer the following questions:

  1. Are all players of Australian nationality? Output those players who are not Australian nationals.
  2. Of those players who scored at least one goal, were all the goals the results of non-penalty kicks? Output those players who scored penalty goals.
  3. Of those players who had at least 1 penalty kick, did the kicks all result in goals?
  4. Of those players who are not Australian nationals, did any of them score goals? Output non-Australian nationals and the number of goals each of those players scored.

:exercise: Implement the function and without using the operator &&.

:exercise: Implement the function or without using the operator ||.

:exercise: Implement the function all without using the operator &&.

:exercise: Implement the function any without using the operator ||.