Порядок в суде!
Класс типов Ord, предназначенный для типов, значения которых могут быть упорядочены, также допускает автоматическое порождение экземпляров. Если сравниваются два значения одного типа, сконструированные с помощью различных конструкторов данных, то меньшим считается значение, конструктор которого определён раньше. Рассмотрим, к примеру, тип Bool, значениями которого могут быть False или True. Для наших целей удобно предположить, что он определён следующим образом:
data Bool = False | True deriving (Ord)
Поскольку конструктор False указан первым, а конструктор True – после него, мы можем считать, что True больше, чем False.
ghci> True `compare` False
GT
ghci> True > False
True
ghci> True < False
False
Если два значения имеют одинаковый конструктор, то при отсутствии полей они считаются равными. Если поля есть, то выполняется их сравнение. Заметьте, что в этом случае типы полей должны быть частью класса типов Ord.
В типе данных Maybe a конструктор значений Nothing указан раньше Just – это значит, что значение Nothing всегда меньше, чем Just <нечто>, даже если это «нечто» равно минус одному миллиону триллионов. Но если мы сравниваем два значения Just, после сравнения конструкторов начинают сравниваться поля внутри них.
ghci> Nothing < Just 100
True
ghci> Nothing > Just (–49999)
False
ghci> Just 3 `compare` Just 2
GT
ghci>Just 100 > Just 50
True
Но сделать что-нибудь вроде Just (*3) > Just (*2) не получится, потому что (*3) и (*2) – это функции, а они не имеют экземпляров для класса Ord.