{-# OPTIONS -XRank2Types #-}
module Control.Monatron.Codensity (
Codensity,
codensity,
runCodensity
) where
import Control.Monatron.MonadT
import Control.Monad.Fix
import Control.Monatron.AutoInstances()
newtype Codensity f a = Codensity {
unCodensity :: forall b. (a -> f b) -> f b
}
codensity :: (forall b. (a -> f b) -> f b) -> Codensity f a
codensity = Codensity
runCodensity :: Monad m => Codensity m a -> m a
runCodensity c = unCodensity c return
instance MonadT Codensity where
lift m = Codensity (m >>=)
c `tbind` f = Codensity (\k -> unCodensity c (\a -> unCodensity (f a) k))
instance MonadFix m => MonadFix (Codensity m) where
mfix f = Codensity $ \k -> mfix (runCodensity. f) >>= k