module Data.Profunctor.Representable
( RepresentableProfunctor(..)
) where
import Data.Functor
import Data.Functor.Identity
import qualified Data.Functor.Compose as Functor
import Data.Profunctor
import qualified Data.Profunctor.Composition as Profunctor
import Control.Comonad
class Functor (Rep k) => RepresentableProfunctor k where
type Rep k :: * -> *
tabulatePro :: (Rep k d -> c) -> k d c
indexPro :: k d c -> Rep k d -> c
instance RepresentableProfunctor (->) where
type Rep (->) = Identity
tabulatePro f = f . Identity
indexPro f (Identity d) = f d
instance Functor w => RepresentableProfunctor (Cokleisli w) where
type Rep (Cokleisli w) = w
tabulatePro = Cokleisli
indexPro = runCokleisli
instance Functor f => RepresentableProfunctor (DownStar f) where
type Rep (DownStar f) = f
tabulatePro = DownStar
indexPro = runDownStar
instance (RepresentableProfunctor f, RepresentableProfunctor g) => RepresentableProfunctor (Profunctor.Compose f g) where
type Rep (Profunctor.Compose f g) = Functor.Compose (Rep g) (Rep f)
tabulatePro f = Profunctor.Compose (tabulatePro id) (tabulatePro (f . Functor.Compose))
indexPro (Profunctor.Compose f g) (Functor.Compose d) = indexPro g $ indexPro f <$> d