2014-02-26 3 views
5

В HaskellWiki's Do notation considered harmful, раздел Полезные приложения, я нашел:Как это getRight :: Либо b -> Может быть, b работает?

Следует отметить, что делать иногда берет бремя от вас писать скучные вещи.

E.g. в

getRight :: Either a b -> Maybe b 
getRight y = 
    do Right x <- y 
     return x 

case на у включен, который вызывает сбой, если у не является правой (т.е. слева), и, таким образом, ничего не возвращает в этом случае.

Вызов fail (Nothing) на несоответствие образов звучит интересно, поэтому я хотел бы попробовать это. Однако синтаксис выглядит неправильно - мы не в монаде Either, так как мы можем извлечь что-нибудь из y?

Действительно, я попробовал, и это дало мне «Не удалось совместить тип« Либо »с« Может быть »». Так что давайте использовать правильный шаблон Искателя, let здесь:

getRight y = do { let (Right x) = y; return x } 

Это дало мне ошибку синтаксиса «синтаксического анализа ошибок на входе`}»». Не то, что я понимаю, почему это не работает, но давайте писать в многострочной нотации:

getRight y = do 
    let (Right x) = y 
    return x 

Ах, что, казалось, работал - разобрать по крайней мере. Однако:

*Main> getRight (Right 5) 
Just 5 
*Main> getRight (Left 5) 
Just *** Exception: […]\test.hs:16:13-25: Irrefutable pattern failed for pattern (Data.Either.Right x) 
-- `Nothing` was expected 

Что дает? Так что я сейчас задаю вопросы:

  • Что здесь произошло? Почему моя линия с запятой не работает?
  • Как это сделать правильно (с do, все остальное тривиально)?
+1

Ошибка parse в 'getRight' заключается в том, что, как только вы переключаетесь на явные фигурные скобки и точки с запятой, тогда все языковые конструкции, вложенные внутрь, должны также использовать явные скобки и точки с запятой:' getRight y = do {let {Right x = y}; return x} ' – kosmikus

+0

@kosmikus: Hm, с этим я получаю« ошибку синтаксического анализа на входе \ '= '*" – Bergi

+0

Не знаю. Работает для меня с помощью ghc-7.4.2, ghc-7.6.3 и ghc-7.8.1-rc1 ... – kosmikus

ответ

9

В примере, вероятно, предназначен, чтобы быть

getRight :: Either a b -> Maybe b 
getRight y = 
    do Right x <- return y -- note: return = Just 
     return x 

, где неудача поиска по шаблону вызывает fail = const Nothing. Она переведена на:

getRight y = let ok (Right x) = do {return x} 
       ok _   = fail "pattern mismatch error" 
      in return y >>= ok 

FWIW самые опытные люди, кажется, думают fail как метод Monad был бородавка. Отъезд MonadPlus для более принципиального подхода к неудаче.

+2

Эта страница, как правило, имеет некоторые проблемы ...например, целые абзацы устарели сноской, в которой говорится, что они устарели (почему бы просто не удалить ее тогда?). – Cubic

+1

Таким образом, только обозначение '<-' вызывает' fail' при несоответствии шаблона, 'let' does not? Может быть, вы можете показать код, который генерирует компилятор, когда он обезжиривает 'do'? – Bergi

Смежные вопросы