Читаем Изучай Haskell во имя добра! полностью

Когда мы применяем функцию landLeft 1 к значению (0, 0), у нас получается результат (1, 0). Затем мы усаживаем птицу на правой стороне, что даёт в результате (1, 1). Наконец, две птицы приземляются на левой стороне, что даёт в результате (3, 1). Мы применяем функцию к чему-либо, сначала записывая функцию, а затем её параметр, но здесь было бы лучше, если бы первым шел шест, а потом функция посадки. Предположим, мы создали вот такую функцию:

x -: f = f x

Можно применять функции, сначала записывая параметр, а затем функцию:

ghci> 100 -: (*3)

300

ghci> True -: not

False

ghci> (0, 0) -: landLeft 2

(2,0)

Используя эту форму, мы можем многократно производить приземление птиц на шест в более «читабельном» виде:

ghci> (0, 0) -: landLeft 1 -: landRight 1 -: landLeft 2

(3,1)

Круто!.. Эта версия эквивалентна предыдущей, где мы многократно усаживали птиц на шест, но выглядит она яснее. Здесь очевиднее, что мы начинаем с (0, 0), а затем усаживаем одну птицу слева, потом одну – справа, и в довершение две – слева.

<p>Я улечу</p>

Пока всё идёт нормально, но что произойдёт, если десять птиц приземлятся на одной стороне?

ghci> landLeft 10 (0, 3)

(10,3)

Десять птиц с левой стороны и лишь три с правой?! Этого достаточно, чтобы отправить в полёт самого Пьера!.. Довольно очевидная вещь. Но что если бы у нас была примерно такая последовательность посадок:

ghci> (0, 0) -: landLeft 1 -: landRight 4 -: landLeft (-1) -: landRight (-2)

(0,2)

Может показаться, что всё хорошо, но если вы проследите за шагами, то увидите, что на правой стороне одновременно находятся четыре птицы – а на левой ни одной! Чтобы исправить это, мы должны ещё раз взглянуть на наши функции landLeft и landRight.

Необходимо дать функциям landLeft и landRight возможность завершаться неуспешно. Нам нужно, чтобы они возвращали новый шест, если равновесие поддерживается, но завершались неуспешно, если птицы приземляются неравномерно. И какой способ лучше подойдёт для добавления к значению контекста неудачи, чем использование типа Maybe? Давайте переработаем эти функции:

landLeft :: Birds –> Pole –> Maybe Pole

landLeft n (left,right)

   | abs ((left + n) - right) < 4 = Just (left + n, right)

   | otherwise                    = Nothing

landRight :: Birds –> Pole –> Maybe Pole

landRight n (left,right)

   | abs (left - (right + n)) < 4 = Just (left, right + n)

   | otherwise                    = Nothing

Вместо того чтобы вернуть значение типа Pole, эти функции теперь возвращают значения типа Maybe Pole. Они по-прежнему принимают количество птиц и прежний шест, как и ранее, но затем проверяют, выведет ли Пьера из равновесия приземление такого количества птиц. Мы используем охранные выражения, чтобы проверить, меньше ли разница в количестве птиц на новом шесте, чем 4. Если меньше, оборачиваем новый шест в конструктор Just и возвращаем это. Если не меньше, возвращаем значение Nothing, сигнализируя о неудаче.

Давайте опробуем этих деток:

ghci> landLeft 2 (0, 0)

Just (2,0)

ghci> landLeft 10 (0, 3)

Nothing

Когда мы приземляем птиц, не выводя Пьера из равновесия, мы получаем новый шест, обёрнутый в конструктор Just. Но когда значительное количество птиц в итоге оказывается на одной стороне шеста, в результате мы получаем значение Nothing. Всё это здорово, но, похоже, мы потеряли возможность многократного приземления птиц на шесте! Выполнить landLeft 1 (landRight 1 (0, 0)) больше нельзя, потому что когда landRight 1 применяется к (0, 0), мы получаем значение не типа Pole, а типа Maybe Pole. Функция landLeft 1 принимает параметр типа Pole, а не Maybe Pole.

Нам нужен способ получения Maybe Pole и передачи его функции, которая принимает Pole и возвращает Maybe Pole. К счастью, у нас есть операция >>=, которая делает именно это для типа Maybe. Давайте попробуем:

ghci> landRight 1 (0, 0) >>= landLeft 2

Just (2,1)

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

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

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

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

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

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

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

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

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