pipes-3.1.0: Control/PFunctor.hs
-- | This module defines functors in the category of proxies
{-# LANGUAGE KindSignatures, Rank2Types #-}
module Control.PFunctor (
-- * Functors over Proxies
PFunctor(..),
hoistPK,
raiseP,
raisePK,
) where
import Control.Proxy.Class (Proxy)
import Control.Proxy.Trans (ProxyTrans(liftP))
{-| A functor in the category of proxies
> hoistP f . hoistP g = hoistP (f . g)
>
> hoistP id = id
If @f@ is a proxy morphism, then @hoistP f@ is a proxy morphism, meaning
that @hoistPK f = (hoistP f .)@ defines a functor between five categories.
Functor between Kleisli categories:
> hoistPK f p1 >=> hoistPK f p2 = hoistPK f (p1 >=> p2)
>
> hoistPK f return = return
Functor between 'P.Proxy' categories:
> hoistPK f p1 >-> hoistPK f p2 = hoistPK f (p1 >-> p2)
>
> hoistPK f idT = idT
> hoistPK f p1 >~> hoistPK f p2 = hoistPK f (p1 >~> p2)
>
> hoistPK f coidT = coidT
Functor between \"request\" categories:
> hoistPK f p1 \>\ hoistPK f p2 = hoistPK f (p2 \>\ p2)
>
> hoistPK f request = request
Functor between \"respond\" categories:
> hoistPK f p1 />/ hoistPK f p2 = hoistPK f (p2 />/ p2)
>
> hoistPK f respond = respond
-}
class PFunctor (t
:: (* -> * -> * -> * -> (* -> *) -> * -> *)
-> * -> * -> * -> * -> (* -> *) -> * -> * ) where
{-| Lift a proxy morphism from @p1@ to @p2@ into a proxy morphism from
@(t p1)@ to @(t p2)@ -}
hoistP
:: (Monad m, Proxy p1)
=> (forall r1 . p1 a' a b' b m r1 -> p2 a' a b' b n r1) -- ^ Proxy morphism
-> ( t p1 a' a b' b m r2 -> t p2 a' a b' b n r2)
-- | Convenience function equivalent to @(hoistP f .)@
hoistPK
:: (Monad m, Proxy p1, PFunctor t)
=> (forall r1 . p1 a' a b' b m r1 -> p2 a' a b' b n r1) -- ^ Proxy morphism
-> (q -> t p1 a' a b' b m r2) -- ^ Proxy Kleisli arrow
-> (q -> t p2 a' a b' b n r2)
hoistPK f = (hoistP f .)
{-| Lift the base proxy
> raiseP = hoistP liftP
-}
raiseP
:: (Monad m, Proxy p, PFunctor t1, ProxyTrans t2)
=> t1 p a' a b' b m r -- ^ Proxy
-> t1 (t2 p) a' a b' b m r
raiseP = hoistP liftP
{-| Lift the base proxy of a \'@K@\'leisli arrow
> raisePK = hoistPK liftP
-}
raisePK
:: (Monad m, Proxy p, PFunctor t1, ProxyTrans t2)
=> (q -> t1 p a' a b' b m r) -- ^ Proxy Kleisli arrow
-> (q -> t1 (t2 p) a' a b' b m r)
raisePK = hoistPK liftP