-- | Extend a monad with the ability to terminate a computation without a value module Mini.Transformers.MaybeT ( -- * Type MaybeT ( MaybeT ), -- * Runner runMaybeT, -- * Operations nothing, anticipate, ) where import Control.Applicative ( Alternative ( empty, (<|>) ), ) import Control.Monad ( ap, liftM, (>=>), ) import Mini.Transformers.Class ( MonadTrans ( lift ), ) {- - Type -} -- | A terminable transformer with inner monad /m/, return /a/ newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) -- ^ Unwrap a 'MaybeT' 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 = MaybeT $ pure 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 {- - Operations -} -- | Terminate the computation without a value nothing :: (Monad m) => MaybeT m a nothing = empty -- | 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