Классы типов
Класс типов – интерфейс, определяющий некоторое поведение. Если тип является экземпляром класса типов, то он поддерживает и реализует поведение, описанное классом типов. Более точно можно сказать, что класс типов определяет набор функций, и если мы решаем сделать тип экземпляром класса типов, то должны явно указать, что эти функции означают применительно к нашему типу.
Хорошим примером будет класс типов, определяющий равенство. Значения многих типов можно сравнивать на равенство с помощью оператора ==. Посмотрим на его сигнатуру:
ghci> :t (==)
(==) :: (Eq a) => a –> a –> Bool
Заметьте: оператор равенства == – это функция. Функциями также являются операторы +, *, –, / и почти все остальные операторы. Если имя функции содержит только специальные символы, по умолчанию подразумевается, что это инфиксная функция. Если мы захотим проверить её тип, передать её другой функции или вызвать как префиксную функцию, мы должны поместить её в круглые скобки.
Интересно… мы видим здесь что-то новое, а именно символ =>. Всё, что находится перед символом =>, называется ограничением класса. Мы можем прочитать предыдущее объявление типа следующим образом: «функция сравнения на равенство принимает два значения одинакового типа и возвращает значение типа Bool. Тип этих двух значений должен быть экземпляром класса Eq» (это и есть ограничение класса).
Класс типа Eq предоставляет интерфейс для проверки на равенство. Каждый тип, для значений которого операция проверки на равенство имеет смысл, должен быть экземпляром класса Eq. Все стандартные типы языка Haskell (кроме типов для ввода-вывода и функций) являются экземплярами Eq.
ПРИМЕЧАНИЕ. Важно отметить, что классы типов в языке Haskell не являются тем же самым, что и классы в объектно-ориентированных языках программирования.
У функции elem тип (Eq a) => a –> [a] –> Bool, потому что она применяет оператор == к элементам списка, чтобы проверить, есть ли в этом списке значение, которое мы ищем.
Далее приводятся описания нескольких базовых классов типов.