В разделе «Классы типов» главы 2 приводились базовые сведения о классах типов. Мы упомянули, что класс типов – это нечто вроде интерфейса, который определяет некоторое поведение. Тип может быть сделан экземпляром класса, если поддерживает это поведение. Пример: тип >Int
есть экземпляр класса типов >Eq
, потому что класс >Eq
определяет поведение для сущностей, которые могут быть проверены на равенство. Так как целые числа можно проверить на равенство, тип >Int
имеет экземпляр для класса >Eq
. Реальная польза от этого видна при использовании функций, которые служат интерфейсом класса >Eq
, – операторов >==
и >/=
. Если тип имеет определённый экземпляр класса >Eq
, мы можем применять оператор >==
к значениям этого типа. Вот почему выражения >4 == 4
и >"раз" /= "два"
проходят проверку типов.
Классы типов часто путают с классами в языках вроде Java, Python, C++ и им подобных, что сбивает с толку множество людей. В вышеперечисленных языках классы – это нечто вроде чертежей, по которым потом создаются объекты, хранящие некое состояние и способные производить некие действия. Мы не создаём типы из классов типов – вместо этого мы сначала создаём свои типы данных, а затем думаем о том, как они могут себя вести. Если то, что мы создали, можно проверить на равенство, – определяем для него экземпляр класса >Eq
. Если наш тип может вести себя как нечто, что можно упорядочить, – создаём для него экземпляр класса >Ord
.
Давайте посмотрим, как язык Haskell умеет автоматически делать наши типы экземплярами таких классов типов, как