#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
#endif
module Data.Profunctor.Composition
(
Procompose(..)
, procomposed
, idl
, idr
, upstars, kleislis
, downstars, cokleislis
) where
import Control.Arrow
import Control.Category
import Control.Comonad
import Control.Monad (liftM)
import Data.Functor.Compose
import Data.Profunctor
import Data.Profunctor.Rep
import Data.Profunctor.Unsafe
import Prelude hiding ((.),id)
data Procompose p q d c where
Procompose :: p d a -> q a c -> Procompose p q d c
procomposed :: Category p => Procompose p p a b -> p a b
procomposed (Procompose pda pac) = pac . pda
instance (Profunctor p, Profunctor q) => Profunctor (Procompose p q) where
dimap l r (Procompose f g) = Procompose (lmap l f) (rmap r g)
lmap k (Procompose f g) = Procompose (lmap k f) g
rmap k (Procompose f g) = Procompose f (rmap k g)
k #. Procompose f g = Procompose f (k #. g)
Procompose f g .# k = Procompose (f .# k) g
instance Profunctor q => Functor (Procompose p q a) where
fmap k (Procompose f g) = Procompose f (rmap k g)
instance (Representable p, Representable q) => Representable (Procompose p q) where
type Rep (Procompose p q) = Compose (Rep p) (Rep q)
tabulate f = Procompose (tabulate (getCompose . f)) (tabulate id)
rep (Procompose f g) d = Compose $ rep g <$> rep f d
instance (Corepresentable p, Corepresentable q) => Corepresentable (Procompose p q) where
type Corep (Procompose p q) = Compose (Corep q) (Corep p)
cotabulate f = Procompose (cotabulate id) (cotabulate (f . Compose))
corep (Procompose f g) (Compose d) = corep g $ corep f <$> d
instance (Strong p, Strong q) => Strong (Procompose p q) where
first' (Procompose x y) = Procompose (first' x) (first' y)
second' (Procompose x y) = Procompose (second' x) (second' y)
instance (Choice p, Choice q) => Choice (Procompose p q) where
left' (Procompose x y) = Procompose (left' x) (left' y)
right' (Procompose x y) = Procompose (right' x) (right' y)
idl :: (Profunctor p, Profunctor q, Functor f)
=> p (q d c) (f (r d' c')) -> p (Procompose (->) q d c) (f (Procompose (->) r d' c'))
idl = dimap (\(Procompose f g) -> lmap f g) (fmap (Procompose id))
idr :: (Profunctor p, Profunctor q, Functor f)
=> p (q d c) (f (r d' c')) -> p (Procompose q (->) d c) (f (Procompose r (->) d' c'))
idr = dimap (\(Procompose f g) -> rmap g f) (fmap (`Procompose` id))
upstars :: (Profunctor p, Functor f, Functor h)
=> p (UpStar (Compose f g) d c) (h (UpStar (Compose f' g') d' c'))
-> p (Procompose (UpStar f) (UpStar g) d c) (h (Procompose (UpStar f') (UpStar g') d' c'))
upstars = dimap hither (fmap yon) where
hither (Procompose (UpStar dfx) (UpStar xgc)) = UpStar (Compose . fmap xgc . dfx)
yon (UpStar dfgc) = Procompose (UpStar (getCompose . dfgc)) (UpStar id)
downstars :: (Profunctor p, Functor g, Functor h)
=> p (DownStar (Compose g f) d c) (h (DownStar (Compose g' f') d' c'))
-> p (Procompose (DownStar f) (DownStar g) d c) (h (Procompose (DownStar f') (DownStar g') d' c'))
downstars = dimap hither (fmap yon) where
hither (Procompose (DownStar fdx) (DownStar gxc)) = DownStar (gxc . fmap fdx . getCompose)
yon (DownStar dgfc) = Procompose (DownStar id) (DownStar (dgfc . Compose))
kleislis :: (Profunctor p, Monad f, Functor h)
=> p (Kleisli (Compose f g) d c) (h (Kleisli (Compose f' g') d' c'))
-> p (Procompose (Kleisli f) (Kleisli g) d c) (h (Procompose (Kleisli f') (Kleisli g') d' c'))
kleislis = dimap hither (fmap yon) where
hither (Procompose (Kleisli dfx) (Kleisli xgc)) = Kleisli (Compose . liftM xgc . dfx)
yon (Kleisli dfgc) = Procompose (Kleisli (getCompose . dfgc)) (Kleisli id)
cokleislis :: (Profunctor p, Functor g, Functor h)
=> p (Cokleisli (Compose g f) d c) (h (Cokleisli (Compose g' f') d' c'))
-> p (Procompose (Cokleisli f) (Cokleisli g) d c) (h (Procompose (Cokleisli f') (Cokleisli g') d' c'))
cokleislis = dimap hither (fmap yon) where
hither (Procompose (Cokleisli fdx) (Cokleisli gxc)) = Cokleisli (gxc . fmap fdx . getCompose)
yon (Cokleisli dgfc) = Procompose (Cokleisli id) (Cokleisli (dgfc . Compose))