Учебник по Haskell | страница 27
В первой функции twice мы воспользовались методом (+) из класса Group, поэтому функция имеет кон-
текст Group a => . А во второй функции isE мы воспользовались методом e из класса Group и методом (==)
из класса Eq, поэтому функция имеет контекст (Group a, Eq a) => .
Контекст классов типов. Суперклассы
Класс типов также может содержать контекст. Он указывается между словом class и именем класса.
Например
class IsPerson a
class IsPerson a => HasName a where
name :: a -> String
Это определение говорит о том, что мы можем сделать экземпляр класса HasName только для тех типов,
которые содержатся в IsPerson. Мы говорим, что класс HasName содержится в IsPerson. В этом случае класс
из контекста IsPerson называют суперклассом для данного класса HasName.
Это сказывается на контексте объявления типа. Теперь, если мы пишем
Классы типов | 19
fun :: HasName a => a -> a
Это означает, что мы можем пользоваться для значений типа a как методами из класса HasName, так и
методами из класса IsPerson. Поскольку если тип принадлежит классу HasName, то он также принадлежит и
IsPerson.
Запись (IsPerson a => HasName a) немного обманывает, было бы точнее писать IsPerson a <= HasName
a, если тип a в классе HasName, то он точно в классе IsPerson, но в Haskell закрепилась другая запись.
1.5 Экземпляры классов типов
В экземплярах (instance) классов типов мы даём конкретное наполнение для методов класса типов. Опре-
деление экземпляра пишется так же, как и определение класса типа, но вместо class мы пишем instance,
вместо некоторого типа наш конкретный тип, а вместо типов методов – уравнения для них.
Определим экземпляры для Bool
Класс Eq:
instance Eq Bool where
(==) True
True
= True
(==) False False = True
(==) _
_
= False
(/=) a b
= not (a == b)
Класс Show:
instance Show Bool where
show True
= ”True”
show False = ”False”
Класс Group:
instance Group Bool where
e
= True
(+) a b = and a b
inv a
= not a
Отметим важность наличия свойств (ограничений) у значений, определённых в классе типов. Так, на-
пример, в классе типов “сравнение на равенство” для любых двух значений данного типа одна из операций
должна вернуть “истину”, а другая “ложь”, то еесть два элемента данного типа либо равны, либо не рав-
ны. Недостаточно определить равенство для конкретного типа, необходимо убедиться в том, что для всех
элементов данного типа свойства понятия равенства не нарушаются.
На самом деле приведённое выше определение экземпляра для Group не верно, хотя по типам оно под-