мы должны явно записывать, на каком шесте садятся птицы, но каждый раз мы просто используем шест, который был результатом предшествующего приземления. Тем не менее это дало нам некоторое представление о нотации >do
.
Сопоставление с образцом и неудача в вычислениях
Привязывая монадические значения к идентификаторам в нотации >do
, мы можем использовать сопоставление с образцом так же, как в выражениях >let
и параметрах функции. Вот пример сопоставления с образцом в выражении >do
:
>justFirst :: Maybe Char
>justFirst = do
> (x:xs) <– Just "привет"
> return x
Мы используем сопоставление с образцом для получения первого символа строки >"привет"
, а затем возвращаем его в качестве результата. Поэтому >justFirst
возвращает значение >Just 'п'
.
Что если бы это сопоставление с образцом окончилось неуспешно? Когда сопоставление с образцом в функции оканчивается не успешно, происходит сопоставление со следующим образцом. Если сопоставление проходит по всем образцам для данной функции с невыполнением их условий, выдаётся ошибка и происходит аварийное завершение работы программы. С другой стороны, сопоставление с образцом, окончившееся неудачей в выражениях >let
, приводит к незамедлительному возникновению ошибки, потому что в выражениях >let
отсутствует механизм прохода к следующему образцу при невыполнении условия.
Когда сопоставление с образцом в выражении >do
завершается неуспешно, функция >fail
(являющаяся частью класса типов >Monad
) позволяет ему вернуть в результате неудачу в контексте текущей монады, вместо того чтобы привести к аварийному завершению работы программы. Вот реализация функции по умолчанию:
>fail :: (Monad m) => String –> m a
>fail msg = error msg
Так что по умолчанию она действительно заставляет программу завершаться аварийно. Но монады, содержащие в себе контекст возможной неудачи (как тип >Maybe
), обычно реализуют её самостоятельно. Для типа >Maybe
она реализована следующим образом:
>fail _ = Nothing
Она игнорирует текст сообщения об ошибке и производит значение >Nothing
. Поэтому, когда сопоставление с образцом оканчивается неуспешно в значении типа >Maybe
, записанном в нотации >do
, результат всего значения будет равен >Nothing
. Предпочтительнее, чтобы ваша программа завершила свою работу неаварийно. Вот выражение >do
, включающее сопоставление с образцом, которое обречено на неудачу:
>wopwop :: Maybe Char
>wopwop = do
> (x:xs) <– Just ""
> return x
Сопоставление с образцом оканчивается неуспешно, поэтому эффект аналогичен тому, как если бы вся строка с образцом была заменена значением >Nothing