{-# LANGUAGE FlexibleInstances , MultiParamTypeClasses , UndecidableInstances , InstanceSigs , LambdaCase #-} module MyMaybeT (MaybeT(..)) where import Control.Monad.Trans.Class import Control.Applicative import Control.Monad.State newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) } instance Functor m => Functor (MaybeT m) where fmap :: (a -> b) -> MaybeT m a -> MaybeT m b fmap f (MaybeT mma) = MaybeT (fmap (fmap f) mma) instance Applicative m => Applicative (MaybeT m) where pure :: a -> MaybeT m a pure a = MaybeT (pure $ Just a) (<*>) :: MaybeT m (a -> b) -> MaybeT m a -> MaybeT m b (MaybeT mf) <*> (MaybeT mx) = MaybeT ((<*>) <$> mf <*> mx) {- instance Monad m => Monad (MaybeT m) where (>>=) :: MaybeT m a -> (a -> MaybeT m b) -> MaybeT m b (MaybeT mx) >>= f = MaybeT $ do v <- mx case v of Nothing -> pure Nothing Just a -> runMaybeT (f a) -} instance Monad m => Monad (MaybeT m) where (>>=) :: MaybeT m a -> (a -> MaybeT m b) -> MaybeT m b (MaybeT ma) >>= f = MaybeT $ ma >>= \case Nothing -> pure Nothing Just a -> runMaybeT (f a) instance MonadTrans MaybeT where lift :: Monad m => m a -> MaybeT m a lift ma = MaybeT $ fmap Just ma instance MonadState s m => MonadState s (MaybeT m) where state :: (s -> (a, s)) -> MaybeT m a state = lift . state instance Applicative m => Alternative (MaybeT m) where empty :: MaybeT m a empty = MaybeT (pure empty) (<|>) :: MaybeT m a -> MaybeT m a -> MaybeT m a (MaybeT mx) <|> (MaybeT my) = MaybeT ((<|>) <$> mx <*> my) {- instance Monad m => MonadPlus (MaybeT m) where mzero = empty mplus = (<|>) -}