这个getRight怎么样?或者是b - >也许b工作?

时间:2014-02-26 21:59:26

标签: haskell pattern-matching do-notation

HaskellWiki's Do notation considered harmful有用的应用部分,我找到了:

  

应该提到的是,有时会承担你的负担   写无聊的东西。

     

E.g。在

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

包括y上的case,如果y不是右,则调用失败(即   左),因此在这种情况下返回Nothing。

在模式不匹配上调用failNothing)听起来很有趣,所以我想尝试一下。但是,语法看起来不对 - 我们不在Either monad中,那么我们如何从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 个答案:

答案 0 :(得分: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,了解更为原则性的失败方法。