Search code examples
haskellpattern-matchingdo-notation

Handle Error in refutable pattern when pattern matching in do notation


Suppose I have a function func :: a -> m (Maybe b), where m is a monad. Then, in a do for m, I can write

example :: a -> m (Maybe b)
example a = do 
  Just x <- func a
.....

If func a = Nothing, this will trigger the fail method of m. Is there a way to still use this notation while specify a catch all pattern matching case? I'm trying to avoid having to add a separate case of expression. I vaguely remember something like this being possible, but I cannot seem to find where I originally saw it. I remember something along the lines of

example :: a -> m (Maybe b)
example a = do 
  Just x <- func a | Nothing -> myfail
.....

I'm worried that I may be recollecting something from a different language, since I can't find anything about this after searching for a while.


Solution

  • You can write:

    do
        x <- func >>= \case
            Just x -> pure x
            Nothing -> myfail
        ...
    

    You do still need to write a case, but it doesn't increase the indentation level like the "obvious" case does:

    do
        mx <- func
        case mx of
            Just x -> do
                ...
            Nothing -> myfail
    

    Notice how much shallower the ... is in the first example than the second.