module Data.Profunctor.Corepresentable
( CorepresentableProfunctor(..)
) where
import Data.Functor
import Data.Functor.Identity
import Data.Profunctor
import Control.Arrow
import qualified Data.Profunctor.Composition as Profunctor
import qualified Data.Functor.Compose as Functor
class Functor (Corep k) => CorepresentableProfunctor k where
type Corep k :: * -> *
cotabulatePro :: (d -> Corep k c) -> k d c
coindexPro :: k d c -> d -> Corep k c
instance CorepresentableProfunctor (->) where
type Corep (->) = Identity
cotabulatePro f = runIdentity . f
coindexPro f = Identity . f
instance Functor m => CorepresentableProfunctor (Kleisli m) where
type Corep (Kleisli m) = m
cotabulatePro = Kleisli
coindexPro = runKleisli
instance Functor f => CorepresentableProfunctor (UpStar f) where
type Corep (UpStar f) = f
cotabulatePro = UpStar
coindexPro = runUpStar
instance (CorepresentableProfunctor c, CorepresentableProfunctor d) => CorepresentableProfunctor (Profunctor.Compose c d) where
type Corep (Profunctor.Compose c d) = Functor.Compose (Corep c) (Corep d)
cotabulatePro f = Profunctor.Compose (cotabulatePro (Functor.getCompose . f)) (cotabulatePro id)
coindexPro (Profunctor.Compose f g) d = Functor.Compose $ coindexPro g <$> coindexPro f d