HaRe-0.6: StrategyLib-4.0-beta/library/MonadMaybe.hs
------------------------------------------------------------------------------
-- |
-- Maintainer : Ralf Laemmel, Joost Visser
-- Stability : experimental
-- Portability : portable
--
-- This module introduces the MaybeT monad transformer.
-- It is basically a simplification of the ErrorT monad transformer.
------------------------------------------------------------------------------
module MonadMaybe (
MaybeT(..)
) where
import Monad
import Control.Monad.Fix
import Control.Monad.Trans
import Control.Monad.Reader
import Control.Monad.Writer
import Control.Monad.State
import Control.Monad.RWS
import Control.Monad.Cont
import IO
import Control.Monad.Error
------------------------------------------------------------------------------
-- | The monad transformer 'MaybeT'.
newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
instance (Monad m) => Functor (MaybeT m) where
fmap f m = MaybeT $ do
a <- runMaybeT m
case a of
Nothing -> return (Nothing)
Just r -> return (Just (f r))
instance (Monad m) => Monad (MaybeT m) where
return a = MaybeT $ return (Just a)
m >>= k = MaybeT $ do
a <- runMaybeT m
case a of
Nothing -> return (Nothing)
Just r -> runMaybeT (k r)
fail msg = MaybeT $ return (Nothing)
instance (Monad m) => MonadPlus (MaybeT m) where
mzero = MaybeT $ return (Nothing)
m `mplus` n = MaybeT $ do
a <- runMaybeT m
case a of
Nothing -> runMaybeT n
Just r -> return (Just r)
instance (MonadFix m) => MonadFix (MaybeT m) where
mfix f = MaybeT $ mfix $ \a -> runMaybeT $ f $ case a of
Just r -> r
_ -> error "empty mfix argument"
{-
instance (Monad m) => MonadError e (MaybeT m) where
throwError l = MaybeT $ return (Nothing)
m `catchError` h = MaybeT $ do
a <- runMaybeT m
case a of
Nothing -> runMaybeT (h l)
Just r -> return (Just r)
-}
instance MonadTrans (MaybeT) where
lift m = MaybeT $ do
a <- m
return (Just a)
instance (MonadIO m) => MonadIO (MaybeT m) where
liftIO = lift . liftIO
instance (MonadReader r m) => MonadReader r (MaybeT m) where
ask = lift ask
local f m = MaybeT $ local f (runMaybeT m)
instance (MonadWriter w m) => MonadWriter w (MaybeT m) where
tell = lift . tell
listen m = MaybeT $ do
(a, w) <- listen (runMaybeT m)
return $ case a of
Nothing -> Nothing
Just r -> Just (r, w)
pass m = MaybeT $ pass $ do
a <- runMaybeT m
return $ case a of
Nothing -> (Nothing, id)
Just (r, f) -> (Just r, f)
instance (MonadState s m) => MonadState s (MaybeT m) where
get = lift get
put = lift . put
instance (MonadCont m) => MonadCont (MaybeT m) where
callCC f = MaybeT $
callCC $ \c ->
runMaybeT (f (\a -> MaybeT $ c (Just a)))
------------------------------------------------------------------------------