module Data.Profunctor.Rep
(
Rep(..), tabulated
, Corep(..), cotabulated
) where
import Control.Arrow
import Control.Comonad
import Data.Functor.Compose
import Data.Functor.Identity
import Data.Profunctor
import Data.Profunctor.Composition
import Data.Proxy
import Data.Tagged
class (Functor f, Profunctor p) => Rep f p where
tabulate :: (d -> f c) -> p d c
rep :: p d c -> d -> f c
instance Rep Identity (->) where
tabulate f = runIdentity . f
rep f = Identity . f
instance (Monad m, Functor m) => Rep m (Kleisli m) where
tabulate = Kleisli
rep = runKleisli
instance Functor f => Rep f (UpStar f) where
tabulate = UpStar
rep = runUpStar
instance (Rep f p, Rep g q) => Rep (Compose f g) (Procompose p q) where
tabulate f = Procompose (tabulate (getCompose . f)) (tabulate id)
rep (Procompose f g) d = Compose $ rep g <$> rep f d
tabulated :: (Profunctor r, Functor h, Rep f p, Rep g q)
=> r (p d c) (h (q d' c'))
-> r (d -> f c) (h (d' -> g c'))
tabulated = dimap tabulate (fmap rep)
class (Functor f, Profunctor p) => Corep f p where
cotabulate :: (f d -> c) -> p d c
corep :: p d c -> f d -> c
instance Corep Identity (->) where
cotabulate f = f . Identity
corep f (Identity d) = f d
instance Functor w => Corep w (Cokleisli w) where
cotabulate = Cokleisli
corep = runCokleisli
instance Corep Proxy Tagged where
cotabulate f = Tagged (f Proxy)
corep (Tagged a) _ = a
instance Functor f => Corep f (DownStar f) where
cotabulate = DownStar
corep = runDownStar
instance (Corep f p, Corep g q) => Corep (Compose g f) (Procompose p q) where
cotabulate f = Procompose (cotabulate id) (cotabulate (f . Compose))
corep (Procompose f g) (Compose d) = corep g $ corep f <$> d
cotabulated :: (Profunctor r, Functor h, Corep f p, Corep g q)
=> r (p d c) (h (q d' c'))
-> r (f d -> c) (h (g d' -> c'))
cotabulated = dimap cotabulate (fmap corep)