【问题标题】:Haskell - Strange do block behaviorHaskell - 奇怪的阻止行为
【发布时间】:2016-10-11 01:01:53
【问题描述】:

在阅读关于MonadPlusHaskell Wikibook 时,我发现以下函数基本上采用CharString 并返回Just (char,tail) 如果这样的字符等于字符串头, 或Nothing 否则:

char :: Char -> String -> Maybe (Char, String)
char c s = do
  let (c':s') = s
  if c == c' then Just (c, s') else Nothing

他们解释说let (c':s') = s 不会产生异常,因为它位于do 块中,当模式失败时,该块将评估为Nothing,但事实并非如此,因为当我尝试它:

*Main> char 'a' ""
*** Exception: exercice2.hs:5:7-17: Irrefutable pattern failed for pattern (c' : s')

所以我不得不将其重写为:

char' :: Char -> String -> Maybe (Char, String)
char' _ [] = Nothing
char' c (c':s') 
  | c == c' = Just (c,s')
  | otherwise = Nothing

它按预期工作......为什么会发生在我身上?

【问题讨论】:

  • 离题:[1] 吹毛求疵:Haskell Wiki /= Haskell Wikibook(这是一个常见的混淆)。 [2] 如果书中确实存在错误,那么报告它是一个非常合适的时机,因为 MonadPlus 章节将在短时间内针对 AMP 进行更新。谢谢!
  • @duplode 好的,我要按照你说的把它改成 Haskell Wikibook
  • Applicative-Monad 提案,即 GHC 7.10 中使Applicative 成为Monad 的超类的更改。举一个任意的例子,guard,它曾经有一个MonadPlus 约束,现在有一个Alternative。这意味着本书的 Monad Transformers 章节中存在一些轻微损坏的代码(在一个示例中使用 guard),并且以正确的方式修复它需要在 MonadPlus 章节中讨论 Alternative
  • (对了,书里的代码我刚刚修好了。)

标签: haskell pattern-matching do-notation


【解决方案1】:

我认为 wiki 是错误的。他们可能将这与 binds 通过 Monad 提供的 fail 函数失败的事实混淆了。所以下面的例子使用来自Maybefail函数,它返回Nothing

char :: Char -> String -> Maybe (Char, String)
char c s = do
  (c':s') <- return s
  if c == c' then Just (c, s') else Nothing

【讨论】:

  • 是的,确实是错误的。很可能该练习的作者打错了let 而不是&lt;-,并且在其间的八年里,它从每个人的指间溜走了(包括我自己!)。
猜你喜欢
  • 1970-01-01
  • 2016-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-18
  • 2014-01-12
相关资源
最近更新 更多