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

мы должны явно записывать, на каком шесте садятся птицы, но каждый раз мы просто используем шест, который был результатом предшествующего приземления. Тем не менее это дало нам некоторое представление о нотации >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