Home > Software engineering >  Haskell : comparing two chars returns true
Haskell : comparing two chars returns true

Time:10-23

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.

  • Related