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

ghci> return (0, 0) >>= landLeft 1 >>= banana >>= landRight 1

Nothing

Функции banana передаётся значение Just (1, 0), но она всегда производит значение Nothing, которое заставляет всё выражение возвращать в результате Nothing. Какая досада!..

Вместо создания функций, которые игнорируют свои входные данные и просто возвращают предопределённое монадическое значение, мы можем использовать функцию >>. Вот её реализация по умолчанию:

(>>) :: (Monad m) => m a –> m b –> m b

m >> n = m >>= \_ –> n

Обычно передача какого-либо значения функции, которая игнорирует свой параметр и всегда возвращает некое предопределённое значение, всегда даёт в результате это предопределённое значение. При использовании монад, однако, нужно принимать во внимание их контекст и значение. Вот как функция >> действует при использовании с типом Maybe:

ghci> Nothing >> Just 3

Nothing

ghci> Just 3 >> Just 4

Just 4

ghci> Just 3 >> Nothing

Nothing

Если мы заменим оператор >> на вызов >>= \_ –>, легко увидеть, что происходит.

Мы можем заменить нашу функцию banana в цепочке на оператор >> и следующее за ним значение Nothing, чтобы получить гарантированную и очевидную неудачу:

ghci> return (0, 0) >>= landLeft 1 >> Nothing >>= landRight 1

Nothing

Как бы это выглядело, если бы мы не сделали разумный выбор, обработав значения типа Maybe как значения с контекстом неудачи и передав их функциям? Вот какой была бы последовательность приземлений птиц:

routine :: Maybe Pole

routine = case landLeft 1 (0, 0) of

   Nothing –> Nothing

   Just pole1 –> case landRight 4 pole1 of

      Nothing –> Nothing

      Just pole2 –> case landLeft 2 pole2 of

         Nothing –> Nothing

         Just pole3 –> landLeft 1 pole3

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

Обратите внимание, каким образом реализация операции >>= для типа Maybe отражает именно эту логику, когда проверяется, равно ли значение Nothing, и действие производится на основе этих сведений. Если значение равно Nothing, она незамедлительно возвращает результат Nothing. Если значение не равно Nothing, она продолжает работу с тем, что находится внутри конструктора Just.

В этом разделе мы рассмотрели, как некоторые функции работают лучше, когда возвращаемые ими значения поддерживают неудачу. Превращая эти значения в значения типа Maybe и заменяя обычное применение функций вызовом операции >>=, мы практически даром получили механизм обработки вычислений, которые могут оканчиваться неудачно. Причина в том, что операция >>= должна сохранять контекст значения, к которому она применяет функции. В данном случае контекстом являлось то, что наши значения были значениями с неуспехом в вычислениях. Поэтому когда мы применяли к таким значениям функции, всегда учитывалась вероятность неуспеха.

<p>Нотация do</p>

Монады в языке Haskell настолько полезны, что они обзавелись своим собственным синтаксисом, который называется «нотация do». Вы уже познакомились с нотацией do в главе 8, когда мы использовали её для объединения нескольких действий ввода-вывода. Как оказывается, нотация do предназначена не только для системы ввода-вывода, но может использоваться для любой монады. Её принцип остаётся прежним: последовательное «склеивание» монадических значений.

Рассмотрим этот знакомый пример монадического применения:

ghci> Just 3 >>= (\x –> Just (show x ++ "!"))

Just "3!"

Это мы уже проходили! Передача монадического значения функции, которая возвращает монадическое значение, – ничего особенного. Заметьте, как параметр x становится равным значению 3 внутри анонимной функции, когда мы выполняем код. Как только мы внутри этой анонимной функции, это просто обычное значение, а не монадическое. А что если бы у нас был ещё один вызов оператора >>= внутри этой функции? Посмотрите:

ghci> Just 3 >>= (\x –> Just "!" >>= (\y –> Just (show x ++ y)))

Just "3!"

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

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

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

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

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

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

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

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

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