Ответ 1
Из Haskell Wikibook:
... фрагмент с лямбдами был "широко эквивалентен" блоку do. Это не точный перевод, потому что в примечании добавляется специальная обработка ошибок совпадения шаблонов.
Рассмотрим следующий пример:
f xs = do
(x:_) <- Just xs
return x
g xs = Just xs >>=
\(x:_) -> return x
Для любого непустого списка эти функции идентичны. Но f []
возвращает Nothing
, а g []
возвращает ошибку, подобную той, которую вы получаете.
Это связано с тем, что нотация do
обрабатывает ошибку по-разному. Класс Monad
имеет функцию fail
. Вы используете монаду списка, которая терпит неудачу, возвращая пустой список. Монада Maybe
реализует его, возвращая Nothing
. В любом случае, ошибка совпадения шаблонов внутри нотации do
обрабатывается с помощью этой функции, следовательно, разница.
Таким образом, правильный способ его перевода:
g xs = Just xs >>=
\xs' -> case xs' of
(x:_) -> return x
[] -> fail "some error"