2016-10-11 79 views
6

在阅读的Haskell维基教科书MonadPlus,我发现了以下功能基本上取CharString并返回Just (char,tail)如果这种炭等于所述线接头,或Nothing否则:Haskell的 - 奇怪做阻止行为

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 

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

+0

题外话:[1]吹毛求疵:Haskell的维基/ = Haskell的维基教科书(它是一种常见的混淆)。 [2]如果书中确实存在一个错误,那么报告它是一个非常恰当的时刻,因为MonadPlus章节将在短时间内更新AMP。谢谢! – duplode

+1

@duplode好的,我将把它改为Haskell Wikibook,正如你所说的 – FtheBuilder

+0

@duplode对不起,因为我的无知,但AMP意味着什么? – FtheBuilder

回答

7

我认为wiki是错误的。他们可能会混淆这一点,绑定失败通过fail函数Monad提供。所以下面的例子将Maybe,它返回Nothing使用fail功能:

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

是的,这确实是错误的。这个练习的作者很可能错误地输入了“let”而不是“< - ”,并且在八年的时间里,它通过每个人的手指滑过(包括我自己在内!)。 – duplode