Читаем Учебник по Haskell полностью

(Succ (Succ (Succ (Succ (Succ (Succ (Succ Zero)))))))

= True

is7

_

= False

С помощью переменных мы даём синонимы поддеревьям. Этими синонимами мы можем пользоваться в

правой части функции. Так в уравнении

addZero (a:[])

мы извлекаем первый элемент из списка, и одновременно говорим о том, что список может содержать

только один элемент. Отметим, что если мы хотим дать синоним всему дереву а не какой-то части, мы просто

пишем на месте аргумента переменную, как в случае функции xor:

xor a b = ...

С помощью безразличной переменной говорим, что нам не важно, что находится у дерева в этом узле.

Уравнения в определении синонима обходятся сверху вниз, поэтому часто безразличной переменной поль-

зуются в смысле “а во всех остальных случаях”, как в:

instance Eq Nat where

(==) Zero

Zero

= True

(==) (Succ a) (Succ b) = a == b

(==) _

_

= False

Переменные и безразличные переменные также могут уходить вглубь дерева сколь угодно далеко (или

ввысь дерева, поскольку первый уровень в строчной записи это корень):

lessThan7 :: Nat -> Bool

lessThan7

(Succ (Succ (Succ (Succ (Succ (Succ (Succ _)))))))

= False

lessThan7

_

= True

Декомпозицию можно применять только к значениям-константам. Проявляется интересная закономер-

ность: если для композиции необходимым элементом было значение со стрелочным типом (функция), то в

случае декомпозиции нам нужно значение с типом без стрелок (константа). Это говорит о том, что все функ-

ции будут полностью применены, то есть константы будут записаны в виде строчной записи дерева. Если мы

ожидаем на входе функцию, то мы можем только дать ей синоним с помощью с помощью переменной или

проигнорировать её безразличной переменной.

Как в

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

Если перевести на русский интерпретатор говорит:

*Nat> Zero Zero

< interactive>:1:1:

Функция ’Zero’ применяется к одному аргументу,

но её тип ’Nat’ не имеет аргументов

В выражении: Zero Zero

В уравнении для ‘it’: it = Zero Zero

Компилятор увидел применение функции f x, далее он посмотрел, что x = Zero, из этого на основе

правила применения он сделал вывод о том, что f имеет тип Nat -> t, тогда он заглянул в f и нашёл там

Zero :: Nat, что и привело к несовпадению типов.

Составим ещё одно выражение с такой же ошибкой:

*Nat> True Succ

< interactive>:6:1:

The function ‘True’ is applied to one argument,

but its type Bool’ has none

In the expression: True Succ

In an equation for ‘it’: it = True Succ

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных