Изучай Haskell во имя добра! (Липовача) - страница 218

и обернуть его так, чтобы оно превратилось в >Just 1. Или можем превратить его в >[1]. Оно могло бы даже стать действием ввода-вывода, которое ничего не делает, а просто выдаёт >1. Функция, которая за это отвечает, называется >pure.

Аппликативное значение можно рассматривать как значение с добавленным контекстом – «причудливое» значение, выражаясь техническим языком. Например, буква >'a' – это просто обычная буква, тогда как значение >Just 'a' обладает неким добавленным контекстом. Вместо типа >Char у нас есть тип >Maybe Char, который сообщает нам, что его значением может быть буква; но значением может также быть и отсутствие буквы. Класс типов >Applicative позволяет нам использовать с этими значениями, имеющими контекст, обычные функции, и этот контекст сохраняется. Взгляните на пример:

>ghci> (*) <$> Just 2 <*> Just 8

>Just 16

>ghci> (++) <$> Just "клингон" <*> Nothing

>Nothing

>ghci> (-) <$> [3,4] <*> [1,2,3]

>[2,1,0,3,2,1]

Поэтому теперь, когда мы рассматриваем их как аппликативные значения, значения типа >Maybe a представляют вычисления, которые могли окончиться неуспешно, значения типа >[a] – вычисления, которые содержат несколько результатов (недетерминированные вычисления), значения типа >IO a – вычисления, которые имеют побочные эффекты, и т. д.

Монады являются естественным продолжением аппликативных функторов и предоставляют решение для следующей проблемы: если у нас есть значение с контекстом типа >m a, как нам применить к нему функцию, которая принимает обычное значение >a и возвращает значение с контекстом? Другими словами, как нам применить функцию типа >a –> m b к значению типа >m a? По существу, нам нужна вот эта функция:

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

Если у нас есть причудливое значение и функция, которая принимает обычное значение, но возвращает причудливое, как нам передать это причудливое значение в данную функцию? Это является основной задачей при работе с монадами. Мы пишем >m>a вместо >f>a, потому что >m означает >Monad; но монады являются всего лишь аппликативными функторами, которые поддерживают операцию >>>=. Функция >>>= называется связыванием.

Когда у нас есть обычное значение типа >a и обычная функция типа >a>–>>b, передать значение функции легче лёгкого: мы применяем функцию к значению как обычно – вот и всё! Но когда мы имеем дело со значениями, находящимися в определённом контексте, нужно немного поразмыслить, чтобы понять, как эти причудливые значения передаются функциям и как учесть их поведение. Впрочем, вы сами убедитесь, что это так же просто, как раз, два, три.