mini-1.6.1.0: Mini/Transformers/MaybeT.hs
-- | Extend a monad with the ability to terminate a computation without a value
module Mini.Transformers.MaybeT (
-- * Type
MaybeT (
MaybeT
),
runMaybeT,
-- * Operations
anticipate,
nothing,
) where
import Control.Applicative (
Alternative,
empty,
(<|>),
)
import Control.Monad (
ap,
liftM,
(>=>),
)
import Control.Monad.IO.Class (
MonadIO,
liftIO,
)
import Mini.Transformers.Class (
MonadTrans,
lift,
)
import Prelude (
Applicative,
Functor,
Maybe (
Just,
Nothing
),
Monad,
MonadFail,
const,
fail,
fmap,
maybe,
pure,
($),
(.),
(<$>),
(<*>),
(>>=),
)
-- Type
-- | A terminable transformer with inner monad /m/, return /a/
newtype MaybeT m a = MaybeT
{ runMaybeT :: m (Maybe a)
-- ^ Unwrap a transformer computation
}
instance (Monad m) => Functor (MaybeT m) where
fmap = liftM
instance (Monad m) => Applicative (MaybeT m) where
pure = MaybeT . pure . Just
(<*>) = ap
instance (Monad m) => Alternative (MaybeT m) where
empty = nothing
m <|> n =
MaybeT $
runMaybeT m
>>= maybe
(runMaybeT n)
(pure . Just)
instance (Monad m) => Monad (MaybeT m) where
m >>= k =
MaybeT $
runMaybeT m
>>= maybe
(pure Nothing)
(runMaybeT . k)
instance MonadTrans MaybeT where
lift = MaybeT . fmap Just
instance (Monad m) => MonadFail (MaybeT m) where
fail = const nothing
instance (MonadIO m) => MonadIO (MaybeT m) where
liftIO = lift . liftIO
-- Operations
-- | Run a computation and get its result
anticipate :: (Monad m) => MaybeT m a -> MaybeT m (Maybe a)
anticipate = lift . runMaybeT . (Just <$>) >=> maybe (pure Nothing) pure
-- | Terminate the computation without a value
nothing :: (Applicative m) => MaybeT m a
nothing = MaybeT $ pure Nothing