имя Show(от англ. show – показывать). Посмотрим на их определения:
Класс Eq:
class Eqa where
( ==) ::a ->a -> Bool
( /=) ::a ->a -> Bool
Класс Show:
1Было бы точнее называть вычислитель редуктором, поскольку мы проводим редукции, или замену эквивалентных значений, но
закрепилось это название. К тому же, редуктор также обозначает прибор.
18 | Глава 1: Основы
class Showa where
show ::a -> String
За ключевым словом classследует имя класса, тип-параметр и ещё одно ключевое слово where. Далее с
отступами пишутся имена определённых в классе значений. Значения класса называются методами .
Мы определяем лишь типы методов, конкретная реализация будет зависеть от типа a. Методы определя-
ются в экземплярах классов типов, мы скоро к ним перейдём.
Программистская аналогия класса типов это интерфейс. В интерфейсе определён набор значений (как
констант, так и функций), которые могут быть применены ко всем типам, которые поддерживают данный
интерфейс. К примеру, в интерфейсе “сравнение на равенство” для некоторого типа a определены две функ-
ции: равно ( ==) и не равно ( /=) с одинаковым типом a ->a -> Bool, или в интерфейсе “печати” для любого
типа a определена одна функция show типа a -> String.
Математическая аналогия класса типов это алгебраическая система. Алгебра изучает свойства объекта в
терминах операций, определённых на нём, и взаимных ограничениях этих операций. Алгебраическая систе-
ма представляет собой набор операций и свойств этих операций. Этот подход позволяет абстрагироваться
от конкретного представления объектов. Например группа – это все объекты данного типа a, для которых
определены значения: константа – единица типа a, бинарная операция типа a ->a ->a и операция взятия
обратного элемента, типа a ->a. При этом на операции накладываются ограничения, называемые свойства-
ми операций. Например, ассоциативность бинарной операции, или тот факт, что единица с любым другим
элементом, применённые к бинарной операции, дают на выходе исходный элемент.
Давайте определим класс для группы:
class Groupa where
e
::a
( +) ::a ->a ->a
inv ::a ->a
Класс с именем Groupимеет для некоторого типа a три метода: константу e ::a, операцию ( +) ::a ->
a ->a и операцию взятия обратного элемента inv ::a ->a.
Как и в алгебре, в Haskell классы типов позволяют описывать сущности в терминах определённых на них
операций или значений. В примерах мы указываем лишь наличие операций и их типы, так же и в классах
типов. Класс типов содержит набор имён его значений с информацией о типах значений.
Определив класс Group, мы можем начать строить различные выражения, которые будут потом интер-
претироваться специфическим для типа образом:
twice :: Groupa =>a ->a
twice a =a +a
isE ::( Groupa, Eqa) =>a -> Bool
isE x =(x ==e)
Обратите внимание на запись Groupa =>и ( Groupa, Eqa) =>. Это называется контекстом объявления
типа. В контексте мы говорим, что данный тип должен быть из класса Groupили из классов Groupи Eq. Это
значит, что для этого типа мы можем пользоваться методами из этих классов.
В первой функции twice мы воспользовались методом ( +) из класса Group, поэтому функция имеет кон-
текст Groupa =>. А во второй функции isE мы воспользовались методом e из класса Groupи методом ( ==)
из класса Eq, поэтому функция имеет контекст ( Groupa, Eqa) =>.
Контекст классов типов. Суперклассы
Класс типов также может содержать контекст. Он указывается между словом classи именем класса.
Например
class IsPersona
class IsPersona => HasNamea where
name ::a -> String
Это определение говорит о том, что мы можем сделать экземпляр класса HasNameтолько для тех типов,
которые содержатся в IsPerson. Мы говорим, что класс HasNameсодержится в IsPerson. В этом случае класс
Читать дальше