module Control.Monad.Trans.ContT where
import Control.Monad.State
import Control.Monad.Reader
newtype ContT m a = ContT { unContT :: forall w . (a -> m w) -> m w }
runContT :: Monad m => ContT m a -> m a
runContT m = unContT m return
instance MonadTrans ContT where
lift m = ContT (\c -> m >>= c)
instance Monad m => Monad (ContT m) where
return x = lift (return x)
m >>= k = ContT (\c -> unContT m (\x -> unContT (k x) c))
fail str = lift (fail str)
instance MonadPlus m => MonadPlus (ContT m) where
mzero = lift mzero
a `mplus` b = ContT (\c -> unContT a c `mplus` unContT b c)
instance Monad m => MonadState s (ContT (ReaderT s m)) where
get = lift ask
put s = ContT (\c -> local (const s) (c ()))