Haskell - Strange do block behavior

While reading the Haskell Wikibook MonadPlus, I found the following function that basically takes Char and String and returns Just (char,tail) if such a char is equal to the string head, or Nothing otherwise:

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

and they explain that let (c':s') = s will not throw an exception, because it is in the do block, which will be evaluated with Nothing when the template fails, but it is not, because when I tried this:

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

So I had to rewrite it to:

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

and it worked as expected ... Why is this happening to me?

+6
source share
1 answer

I think the wiki is wrong. They are probably confused by the fact that a binding failure occurs with the fail function of a Monad . Thus, the following example will use the fail function of Maybe , which returns Nothing :

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