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

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

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

newtype Codensity (t :: * -> *) (b :: *) (a :: *) =
        Codensity { codensity :: (a -> t b) -> t b }

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

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