【问题标题】:How does this getRight :: Either a b -> Maybe b work?这个 getRight :: Either a b -> Maybe b 是如何工作的?
【发布时间】:2014-02-26 21:59:25
【问题描述】:

HaskellWiki's Do notation considered harmful有用的应用程序部分,我发现:

值得一提的是,do有时会承担你的负担 写无聊的东西。

例如在

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

包含 y 上的 case,如果 y 不是 Right(即 Left),因此在这种情况下返回 Nothing。

在模式不匹配时调用fail (Nothing) 听起来很有趣,所以我想试试这个。但是,语法看起来是错误的——我们不在Either monad 中,那么我们如何从y 中提取任何内容?

确实,我试过了,它给了我“无法将类型 `Either a' 与 `Maybe' 匹配”。所以让我们在这里使用正确的模式匹配器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,其他一切都很简单)?

【问题讨论】:

  • getRight 的解析错误是因为一般来说,一旦切换到显式大括号和分号,那么嵌套在其中的所有语言结构也必须使用显式大括号和分号:getRight y = do { let { Right x = y }; return x }
  • @kosmikus:嗯,我收到“输入 `=' 解析错误”
  • 不知道。为我使用 ghc-7.4.2、ghc-7.6.3 和 ghc-7.8.1-rc1 ...
  • @kosmikus:呃,没关系。完全初学者的错误:我忘记了 ghci let getRight x = 中的第一个 let ...

标签: haskell pattern-matching do-notation


【解决方案1】:

这个例子可能是

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 了解可能更有原则的失败方法。

【讨论】:

  • 该页面通常存在一些问题...例如,整个段落都已过时,并且脚注表明它们已过时(为什么不直接删除它呢?)。
  • 所以只有&lt;- 表示法在模式不匹配时调用faillet 不会?您能否显示编译器在对do 脱糖时生成的代码?
猜你喜欢
  • 1970-01-01
  • 2011-11-06
  • 2015-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-18
  • 2019-10-23
相关资源
最近更新 更多