4

Is there a reason that would explain whether such results are to be expected? Are they better than being undefined?

>>> any (const True) []
False

>>> any (const False) []
False

>>> or []
False

>>> and []
True

I don't really understand what the Report is trying to say:

-- and returns the conjunction of a Boolean list. For the result to be
-- True, the list must be finite; False, however, results from a False
-- value at a finite index of a finite or infinite list. or is the
-- disjunctive dual of and. 
and, or     :: [Bool]    -> Bool
and         =  foldr    (&&)    True
or          =  foldr    (||)    False
sevo
  • 4,559
  • 1
  • 15
  • 31
  • 2
    Well `and` is basically making a `fold` with `&&` for all elements, but one needs initially `True` (since otherwise the result is always `False`, regardless of the values). – Willem Van Onsem Dec 22 '18 at 22:05
  • 3
    This is pretty standard handling across languages. For example, [here's the same question in Java](https://stackoverflow.com/questions/30223079/why-does-stream-allmatch-return-true-for-an-empty-stream). The concept is known as "vacuous truth". – user2357112 Dec 22 '18 at 22:09
  • 1
    Note that, for the same reason, `sum [] == 0` and `product [] == 1`. – chi Dec 22 '18 at 22:47

2 Answers2

9

To expand on the answer by Dan, the conjunction of an empty list of truth values being true True allows you to extend the expected properties of conjunction to that case.

For instance, we would expect that,

and (xs ++ ys) = (and xs) && (and ys) 

and for all xs we have, xs = xs ++ [] so,

  and xs 
= and (xs ++ [])
= (and xs) && (and []) 

considering that and xs might be True or False it follows that,

True  = True  && (and [])
False = False && (and [])

Therefore we must have that and [] is True.

8

This is true of most languages with comparable functions. It is because "True" is the identity of "&&" (meaning x && True == x). Likewise, "False" is the identity of "||" (meaning x || False == x).

Dan Burton
  • 53,238
  • 27
  • 117
  • 198