module DeepControl.Monad.Maybe (
MaybeT(..), mapMaybeT, liftCatch,
) where
import DeepControl.Applicative
import DeepControl.Monad
import DeepControl.MonadTrans
import DeepControl.Commutative
import Control.Monad.Signatures
newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }
instance (Functor m) => Functor (MaybeT m) where
fmap f mv = MaybeT $ f |$>> runMaybeT mv
instance (Monad m) => Applicative (MaybeT m) where
pure = MaybeT . (**:)
f <*> v = MaybeT $ runMaybeT f |*>> runMaybeT v
instance (Monad m) => Monad (MaybeT m) where
return = pure
mv >>= f = MaybeT $
runMaybeT mv >>== \v ->
runMaybeT (f v)
instance MonadTrans MaybeT where
trans = MaybeT . (-*)
instance (MonadIO m) => MonadIO (MaybeT m) where
liftIO = trans . liftIO
mapMaybeT :: (m (Maybe a) -> n (Maybe b)) -> MaybeT m a -> MaybeT n b
mapMaybeT f = MaybeT . f . runMaybeT
liftCatch :: Catch e m (Maybe a) -> Catch e (MaybeT m) a
liftCatch catchE m h = MaybeT $ runMaybeT m `catchE` \e -> runMaybeT (h e)