2016-10-11 82 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