I have two compare to chars: '2' < 'a'. I typed this into my console and it returned true. Why is that?
CodePudding user response:
Because the character 2
comes before the character a
in the ASCII table.
Indeed, 2
's decimal code is 50, whereas a
's decimal code is 97, so the latter occurs 97 - 50 = 47 characters after the former, as demonstrated by this:
iterate succ '2' !! 47
which gives back 'a'
. iterate
has signature (a -> a) -> a -> [a]
, and guess what it does, iterate f x
is the infinite list [x, f x, f (f x), f (f (f x)), …]
, from which we take the 47th element via !! 47
.
CodePudding user response:
Both values, 2
and a
are of type Char
.
-- GHCi
:t '2' -- Char
:t 'a' -- Char
In Haskell, a Char is a 32 bit integer. So, the question is, can we use the operator <
to compare these integers? Yes!
:i Char -- instance Ord Char -- Defined in `GHC.Classes'
So, Haskell says that Char
can be ordered, because it is in class Ord
, and we can use operators like <
to compare them.
If I go on Hoogle, the Haskell version of Google, I can see the definition of the Ord
class, by simply typing Ord
into the search box.
(<), (<=), (>), (>=) :: a -> a -> Bool
max, min :: a -> a -> a
compare x y = if x == y then EQ
-- NB: must be '<=' not '<' to validate the
-- above claim about the minimal things that
-- can be defined for an instance of Ord:
else if x <= y then LT
else GT
x < y = case compare x y of { LT -> True; _ -> False }
x <= y = case compare x y of { GT -> False; _ -> True }
x > y = case compare x y of { GT -> True; _ -> False }
x >= y = case compare x y of { LT -> False; _ -> True }
Char
is a type which is not quite UTF-32 compliant. In UTF-32, the ASCII codes are stored in the bottom 7 bits, 00 through 7F hex. In ASCII, a
is 97 dec, 61 hex, and 2
is 50 dec, 32 hex and hence when we compare the 32 bit values, 2
is indeed less than a
. The declared function (<)
returns True.