content: -- file: ch18/MaybeT.hs
  newtype MaybeT m a = MaybeT {
        runMaybeT :: m (Maybe a)
      }
  
  -- file: ch18/MaybeT.hs
  bindMT :: (Monad m) => MaybeT m a -> (a -> MaybeT m b) -> MaybeT m b
  
  -- file: ch18/MaybeT.hs
  x `bindMT` f = MaybeT $ do
                   unwrapped <- runMaybeT x
                   case unwrapped of
                     Nothing -> return Nothing
                     Just y -> runMaybeT (f y)
  
  -- file: ch18/MaybeT.hs
  x `altBindMT` f =
      MaybeT $ runMaybeT x >>= maybe (return Nothing) (runMaybeT . f)
  
  -- file: ch18/MaybeT.hs
  returnMT :: (Monad m) => a -> MaybeT m a
  returnMT a = MaybeT $ return (Just a)
  
  failMT :: (Monad m) => t -> MaybeT m a
  failMT _ = MaybeT $ return Nothing
   
  instance (Monad m) => Monad (MaybeT m) where
    return = returnMT
    (>>=) = bindMT
    fail = failMT
  
  -- file: ch18/MaybeT.hs
  instance MonadTrans MaybeT where
      lift m = MaybeT (Just `liftM` m)
  
  -- file: ch18/MaybeT.hs
  instance (MonadIO m) => MonadIO (MaybeT m) where
    liftIO m = lift (liftIO m)
  
  instance (MonadState s m) => MonadState s (MaybeT m) where
    get = lift get
    put k = lift (put k)
  
  -- ... and so on for MonadReader, MonadWriter, etc ...
  
  -- file: ch18/MaybeT.hs
  {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses,
               UndecidableInstances #-}
  