Учебник по Haskell | страница 45
Глава 3
Типы
С помощью типов мы определяем все возможные значения в нашей программе. Мы определяем основные
примитивы и способы их комбинирования. Например в типе Nat:
data Nat = Zero | Succ Nat
Один конструктор-примитив Zero, и один конструктор Succ, с помощью которого мы можем делать со-
ставные значения. Определив тип Nat таким образом, мы говорим, что значения типа Nat могут быть только
такими:
Zero,
Succ Zero,
Succ (Succ Zero), Succ (Succ (Succ Zero)), ...
Все значения являются цепочками Succ с Zero на конце. Если где-нибудь мы попытаемся построить значе-
ние, которое не соответствует нашему типу, мы получим ошибку компиляции, то есть программа не пройдёт
проверку типов. Так типы описывают множество допустимых значений.
Значения, которые проходят проверку типов мы будем называть допустимыми, а те, которые не проходят
соответственно недопустимыми. Так например следующие значения недопустимы для Nat
Succ Zero Zero,
Succ Succ, True, Zero (Zero Succ), ...
Недопустимых значений конечно гораздо больше. Такое проявляется и в естественном языке, бессмыс-
ленных комбинаций слов гораздо больше, чем осмысленных предложений. Обратите внимание на то, что мы
говорим о значениях (не)допустимых для некоторого типа, например значение True допустимо для Bool, но
недопустимо для Nat.
Сами типы строятся не произвольным образом. Мы узнали, что при их построении используются две ос-
новные операции, это сумма и произведение типов. Это говорит о том, что в типах должны быть какие-то
закономерности, которые распространяются на все значения. В этой главе мы посмотрим на эти закономер-
ности.
3.1 Структура алгебраических типов данных
Итак у нас лишь две операции: сумма и произведение. Давайте для начала рассмотрим два крайних
случая.
• Только произведение типов
data T = Name T1 T2 ... TN
Мы говорим, что значение нашего нового типа T состоит из значений типов T1, T2, … , TN и у нас есть
лишь один способ составить значение этого типа. Единственное, что мы можем сделать это применить
к значениям типов Ti конструктор Name.
Пример:
data Time = Time Hour Second Minute
• Только сумма типов
data T = Name1 | Name2 | ... | NameN
40 | Глава 3: Типы
Мы говорим, что у нашего нового типа T может быть лишь несколько значений, и перечисляем их в
альтернативах через знак |.
Пример:
data Bool = True | False
Сделаем первое наблюдение: каждое произведение типов определяет новый конструктор. Число кон-
структоров в типе равно числу альтернатив. Так в первом случае у нас была одна альтернатива и следова-