FtheBuilder
FtheBuilder

Reputation: 1437

Haskell - Strange do block behavior

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

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

and they explain that let (c':s') = s will not produce an exception, cause it is in a do block which would evaluate to Nothing when the pattern fails, but, that isn't the case, because when I tried it:

*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 it happening to me?

Upvotes: 6

Views: 169

Answers (1)

Alec
Alec

Reputation: 32319

I think the wiki is wrong. They are probably confusing this with the fact that binds fail via the fail function a Monad affords. So the following example will use the fail function from Maybe, which returns Nothing:

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

Upvotes: 7

Related Questions