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. Udo.
signature.asc
Description: Digital signature
_______________________________________________ Haskell-Cafe mailing list [email protected] http://www.haskell.org/mailman/listinfo/haskell-cafe
