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

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

В данном случае операция >>>= принимала бы значение типа >Maybe a и функцию типа >a –> Maybe b и каким-то образом применяла бы эту функцию к значению >Maybe a. Чтобы понять, как она это делает, мы будем исходить из того, что тип >Maybe является аппликативным функтором. Скажем, у нас есть анонимная функция >\x –> Just (x+1). Она принимает число, прибавляет к нему >1 и оборачивает его в конструктор >Just:

>ghci> (\x –> Just (x+1)) 1

>Just 2

>ghci> (\x –> Just (x+1)) 100

>Just 101

Если мы передадим ей значение >1, она вернёт результат >Just 2. Если мы дадим ей значение >100, результатом будет >Just 101. Это выглядит очень просто. Но как нам передать этой функции значение типа >Maybe? Если мы подумаем о том, как тип >Maybe работает в качестве аппликативного функтора, ответить на этот вопрос будет довольно легко. Мы передаём функции значение >Just, берём то, что находится внутри конструктора >Just, и применяем к этому функцию. Если мы даём ей значение >Nothing, то у нас остаётся функция, но к ней нечего (>Nothing) применить. В этом случае давайте сделаем то же, что мы делали и прежде, и скажем, что результат равен >Nothing.

Вместо того чтобы назвать функцию >>>=, давайте пока назовём её >applyMaybe. Она принимает значение типа >Maybe a и функцию, которая возвращает значение типа >Maybe b, и умудряется применить эту функцию к значению типа >Maybe a. Вот она в исходном коде:

>applyMaybe :: Maybe a –> (a –> Maybe b) –> Maybe b

>applyMaybe Nothing f = Nothing

>applyMaybe (Just x) f = f x

Теперь давайте с ней поиграем. Мы будем использовать её как инфиксную функцию так, чтобы значение типа >Maybe было слева, а функция была справа:

>ghci> Just 3 `applyMaybe` \x –> Just (x+1)

>Just 4

>ghci> Just "смайлик" `applyMaybe` \x –> Just (x ++ " :)")

>Just "смайлик :)"

>ghci> Nothing `applyMaybe` \x –> Just (x+1)

>Nothing

>ghci> Nothing `applyMaybe` \x –> Just (x ++ " :)")

>Nothing

В данном примере, когда мы использовали функцию >applyMaybe со значением >Just и функцией, функция просто применялась к значению внутри конструктора >Just. Когда мы попытались использовать её со значением >Nothing, весь результат был равен >Nothing. Что насчёт того, если функция возвращает >Nothing? Давайте посмотрим:

>ghci>Just 3 `applyMaybe` \x –> if x > 2 then Just x else Nothing