как с помощью переменных можно перетаскивать значения из аргументов в результат.
Ядро Haskell | 21
Классы типов
Нам встретилась одна конструкция определения классов типов:
class Name a where
method1 :: a -> ...
method2 :: a -> ...
...
methodN :: a -> ...
Экземпляры классов типов
Нам встретилась одна конструкция определения экземпляров классов типов:
instance Name Type where
method1 x1 ... xN = ...
method2 x1 ... xM = ...
...
methodN x1 ... xP = ...
Типы, значения и классы типов
Каждое значение имеет тип. Значение v имеет тип T на Haskelclass="underline"
v :: T
Функциональный тип обозначается стрелкой: a -> b
fun :: a -> b
Тип значения может иметь контекст, он говорит о том, что параметр должен принадлежать классу типов:
fun1 :: С a
=> a -> a
fun2 :: (C1 a, C2, ... , CN) => a -> a
Суперклассы
Также контекст может быть и у классов, запись
class A a => B a where
...
Означает, что класс B целиком содержится в A, и перед тем как объявлять экземпляр для класса B, необ-
ходимо определить экземпляр для класса A. При этом класс A называют суперклассом для B.
1.7 Двумерный синтаксис
Наверное вы обратили внимание на то, что в Haskell нет разделителей строк и дополнительных скобок,
которые бы указывали границы определения классов или функций. Компилятор Haskell ориентируется по
переносам строки и отступам.
Так если мы пишем в классе:
class Eq a where
(==) :: a -> a -> a
(/=) :: a -> a -> a
По отступам за первой строкой определения компилятор понимает, что класс содержит два метода. Если
бы мы написали:
class Eq a where
(==) :: a -> a -> a
(/=) :: a -> a -> a
22 | Глава 1: Основы
То смысл был бы совсем другим. Теперь мы определяем класс Eq с одним методом == и указываем тип
некоторого значения (/=). Основное правило такое: конструкции, расположенные на одном уровне, вырав-
ниваются с помощью отступов. Чем правее находится определение, тем глубже оно вложено в какую-нибудь
специальную конструкцию. Пока нам встретилось лишь несколько специальных конструкций, но дальше
появятся и другие. Часто отступы набираются с помощью табуляции. Это удобно. Но лучше пользоваться
пробелами или настроить ваш любимый текстовый редактор так, чтобы он автоматически заменял табуля-
цию на пробелы. Зачем это нужно? Дело в том, что в разных редакторах на табуляцию может быть назначено
разное количество пробелов, так код набранный с двухзначной табуляцией будет очень трудно прочитать
если открыть его в редакторе с четырьмя пробелами вместо табуляции. Поскольку очень часто табуляция
перемежается с пробелами и выравнивание может “поехать”. Поэтому признаком хорошего стиля в Haskell
считается полный отказ от табуляции.
1.8 Краткое содержание
Итак подведём итоги: у нас есть две операции для определения типов (сумма и произведение) и по одной
для значений (синонимы), классов типов и экземпляров. А также бесконечное множество их комбинаций, из
которых и состоит увлекательный мир Haskell. Конечно не только из них, есть нюансы, синтаксический сахар,
расширения языка. Об этом и многом другом мы узнаем из этой книги.
Интересно, что в Haskell, несмотря на обилие конструкций и библиотек, ты чувствуешь, что за ними стоит
нечто из мира науки, мира чистого знания. Ты не просто учишься пользоваться определёнными функциями
или классами, а узнаёшь что-то новое и красивое.
1.9 Упражнения
Потренируйтесь в описаниях в рамках системы типов. Вы определяете базовые понятия и способы их
комбинирования. У вас есть три операции:
• Сумма типов data T = A1 | A2. Перечисление альтернатив
• Произведение типов data T = S S1 S2. Этим мы говорим, что понятие состоит из нескольких.
• Взятие в список [T]. Обозначает множественное число, элементов типа T их может быть несколько.
Опишите что-либо: комнату, дорогу, город, человека, главу из книги, математическую теорию, всё что