Учебник по Haskell | страница 54
случае декомпозиции нам нужно значение с типом без стрелок (константа). Это говорит о том, что все функ-
ции будут полностью применены, то есть константы будут записаны в виде строчной записи дерева. Если мы
ожидаем на входе функцию, то мы можем только дать ей синоним с помощью с помощью переменной или
проигнорировать её безразличной переменной.
Как в
name
(Succ (Succ Zero))
= ...
name
(Zero : Succ Zero : [])
= ...
Но не
name
Succ
= ...
name
(Zero :)
= ...
Отметим, что для композиции это допустимые значения, в первом случае это функция Nat -> Nat, а во
втором это функция типа [Nat] -> [Nat].
Ещё одна особенность декомпозиции заключается в том, что при декомпозиции мы можем пользоваться
только “настоящими” значениями, то есть конструкторами, объявленными в типах. В случае композиции мы
могли пользоваться как конструкторами, так и синонимами.
Например мы не можем написать в декомпозиции:
name
(add Zero Zero)
= ...
name
(or (xor a b) True)
= ...
В Haskell декомпозицию принято называть сопоставлением с образцом (pattern matching). Термин намекает
на то, что в аргументе мы выписываем шаблон (или заготовку) для целого набора значений. Наборы значений
могут получиться, если мы пользуемся переменными. Конструкторы дают нам возможность зафиксировать
вид ожидаемого на вход дерева.
Структура функций | 49
3.4 Проверка типов
В этом разделе мы поговорим об ошибках проверки типов. Почти все ошибки, которые происходят в
Haskell, связаны с проверкой типов. Проверка типов происходит согласно правилам применения, которые
встретились нам в разделе о композиции значений. Мы остановимся лишь на случае для префиксной формы
записи, правила для сечений работают аналогично. Давайте вспомним основное правило:
f :: a -> b,
x :: a
--------------------------
(f x) :: b
Что может привести к ошибке? В этом правиле есть два источника ошибки.
• Тип f не содержит стрелок, или f не является функцией.
• Типы x и аргумента для f не совпадают.
Вот и все ошибки. Универсальное представление всех функций в виде функций одного аргумента, значи-
тельно сокращает число различных видов ошибок. Итак мы можем ошибиться применяя значение к константе
и передав в функцию не то, что она ожидает.
Потренируемся в интерпретаторе, сначала попытаемся создать ошибку первого типа:
*Nat> Zero Zero
< interactive>:1:1:
The function ‘Zero’ is applied to one argument,
but its type ‘Nat’ has none
In the expression: Zero Zero
In an equation for ‘it’: it = Zero Zero
Если перевести на русский интерпретатор говорит: