Learn You a Haskell presents the Bool
type:
data Bool = False | True deriving (Ord)
I don't understand the reason for comparing Bool
's.
> False `compare` True
LT
> True `compare` False
GT
What would be lost if Bool
did not derive from Ord
?
Bool
forms a bounded lattice* where False
is bottom and True
is top. This bounded lattice defines a (total) ordering where False
really is strictly less than True
. (They are also the only elements of this lattice.)
The boolean operations and
and or
can also be looked at as meet and join, respectively, in this lattice. Meet finds the greatest lower bound and join finds the least upper bound. This means that a && False = False
is the same thing as saying that the lower bound of bottom and anything else is bottom, and a || True = True
is the same thing as saying that the upper bound of top and anything is top. So meet and join, which use the ordering property of the booleans, are equivalent to the boolean operations you are familiar with.
You can use min
and max
to show this in Haskell:
False `min` True = False -- this is the greatest lower bound
False && True = False -- so is this
False `max` True = True -- this is the least upper bound
False || True = True -- so is this
This shows that you can define &&
and ||
just from the derived Ord
instance:
(&&) = min
(||) = max
Note that these definitions are not equivalent in the presence of a different kind of bottom because (&&)
and (||)
are short-circuiting (non-strict in the second argument when the first is False
or True
, respectively) while min
and max
are not.
Also, a small correction: The deriving
clause does not say thatBool
"derives from" Ord
. It instructs GHC to derive an instance of the typeclass Ord
for the type Bool
.
* More specifically, a complemented distributive lattice. More specifically still, a boolean algebra.
The Ord
instance for Bool
becomes much more important when you need to compare values that contain Bool
somewhere inside. For example, without it we wouldn't be able to write expressions like:
[False,True] `compare` [False,True,False]
(3, False) < (3, True)
data Person = Person { name :: String, member :: Bool } deriving (Eq, Ord)
etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With