module Data.Functor.Codensity (Codensity (..)) where

import "morphisms" Control.Morphism ((.), ($))

import Control.Functor.Covariant (Covariant ((<$>)))
import Control.Functor.Covariant.Pointable (Pointable (point))

data Codensity (t :: * -> *) (a :: *) = forall b .
        Codensity { codensity :: (a -> t b) -> t b }

instance Covariant (Codensity t) where
        f <$> Codensity x = Codensity $ x . (. f)

instance Pointable (Codensity t) where
        point x = Codensity ($ x)