Порядок в суде!

Класс типов 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.