module Control.Monad.Codensity (
Codensity(..),
toCodensity,
fromCodensity,
module Control.Monad,
) where
import Control.Monad
import Control.Monad.Fix
newtype Codensity f a = Codensity {
runCodensity :: forall b. (a -> f b) -> f b
}
instance Functor (Codensity f) where
fmap f m = Codensity (\k -> runCodensity m (k. f))
instance Monad (Codensity f) where
return a = Codensity (\k -> k a)
c >>= f = Codensity (\k -> runCodensity c (\a -> runCodensity (f a) k))
toCodensity :: Monad m => m a -> Codensity m a
toCodensity m = Codensity (m >>=)
fromCodensity :: Monad m => Codensity m a -> m a
fromCodensity c = runCodensity c return
instance MonadFix m => MonadFix (Codensity m) where
mfix f = Codensity $ \k -> mfix (fromCodensity. f) >>= k