[Haskell-cafe] MaybeT, guards and run-time pattern matching failure

Udo Stenzel u.stenzel at web.de
Tue Nov 1 15:24:33 EST 2005

Joel Reymont wrote:
> I'm trying to optimize this and I thought that things that return  
> Nothing in the Maybe monad should fail the whole computation  
> sequence.

No, it shouldn't.  'return Nothing' ist a perfectly valid result of type
'Maybe (Maybe a)', which is not what you want.  However, 'mzero' _does_
fail the whole computation and may backtrack into an alternative if you
used 'mplus' somewhere.

> timeout :: forall a.Int -> IO a -> IO (Maybe a)
> ...
>        (ssl', tob, fromb) <- liftIO $ timeout 0 startSSL -- bummer, see below

This is quite understandable, as 'timeout ...' gives a 'Maybe (...)' it
won't match  a tuple.  Your second idea is right on point:

>     (Just h) <- liftIO $ timeout 0 $ connect_ h p -- no complains about this

> but when the connection times out (i'm making it with a delay of 0) I  
> get the following runtime error:

A pattern match failure at this point causes 'fail' to be called, which
for exactly this reason is a method of class Monad.  You didn't define
it, therefore you get the default behaviour, and that is to call
'error'.  The fix is straight forward:

> instance (Monad m) => Monad (MaybeT m) where
>     (MaybeT mon) >>= f =
>         MaybeT (mon >>= maybe (return Nothing) (runMaybeT . f))
>     return              = MaybeT . return . Just
>     fail _              = MaybeT (return Nothing)
Of couse you could also bind the result of 'timeout' to a variable and
pattern match on that using 'case'.  That gives you  more freedom and
more ugliness, too.

BTW, if you use 'ErrorT' from Control.Monad.Error instead of MaybeT, you
also get a nice error message instead of a plain Nothing.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://www.haskell.org//pipermail/haskell-cafe/attachments/20051101/747d0c76/attachment.bin

More information about the Haskell-Cafe mailing list