{-# LANGUAGE GADTs #-}
module MaybeT.Deep where
import qualified Control.Monad.Trans as CMT
import qualified Control.Monad as CM
-- Maybe Monad Transformer
instance Monad m => Monad (MaybeT m) where
return = returnMT
(>>=) = bindMT
fail = failMT
instance CMT.MonadTrans MaybeT where
lift = liftMT
returnMT :: Monad m => a -> MaybeT m a
bindMT :: Monad m => MaybeT m a -> (a -> MaybeT m b) -> MaybeT m b
failMT :: Monad m => t -> MaybeT m a
liftMT :: Monad m => m a -> MaybeT m a
runMaybeT:: Monad m => MaybeT m a -> m (Maybe a)
-- Deep embedding
data MaybeT m a where
Return :: a -> MaybeT m a
(:>>=) :: MaybeT m a -> (a -> MaybeT m b) -> MaybeT m b
Fail :: MaybeT m a
Lift :: m a -> MaybeT m a
returnMT = Return
bindMT = (:>>=)
failMT _ = Fail
liftMT = Lift
runMaybeT (Return x) = return (Just x)
runMaybeT (Lift m) = CM.liftM Just m
runMaybeT Fail = return Nothing
runMaybeT (m :>>= f) = do
r <- runMaybeT m
case r of
Nothing -> return Nothing
Just x -> runMaybeT (f x)