{-# LANGUAGE CPP #-}
{-# LANGUAGE MultiParamTypeClasses #-}
#if __GLASGOW_HASKELL__ >= 702 && __GLASGOW_HASKELL__ < 710
{-# LANGUAGE Trustworthy #-}
#endif
module Control.Comonad.Trans.Adjoint
( Adjoint
, runAdjoint
, adjoint
, AdjointT(..)
) where
import Prelude hiding (sequence)
#if __GLASGOW_HASKELL__ < 710
import Control.Applicative
#endif
import Control.Comonad
import Control.Comonad.Trans.Class
import Data.Functor.Adjunction
import Data.Functor.Extend
import Data.Functor.Identity
import Data.Distributive
type Adjoint f g = AdjointT f g Identity
newtype AdjointT f g w a = AdjointT { forall (f :: * -> *) (g :: * -> *) (w :: * -> *) a.
AdjointT f g w a -> f (w (g a))
runAdjointT :: f (w (g a)) }
adjoint :: Functor f => f (g a) -> Adjoint f g a
adjoint :: forall (f :: * -> *) (g :: * -> *) a.
Functor f =>
f (g a) -> Adjoint f g a
adjoint = forall (f :: * -> *) (g :: * -> *) (w :: * -> *) a.
f (w (g a)) -> AdjointT f g w a
AdjointT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. a -> Identity a
Identity
runAdjoint :: Functor f => Adjoint f g a -> f (g a)
runAdjoint :: forall (f :: * -> *) (g :: * -> *) a.
Functor f =>
Adjoint f g a -> f (g a)
runAdjoint = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Identity a -> a
runIdentity forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) (g :: * -> *) (w :: * -> *) a.
AdjointT f g w a -> f (w (g a))
runAdjointT
instance (Adjunction f g, Functor w) => Functor (AdjointT f g w) where
fmap :: forall a b. (a -> b) -> AdjointT f g w a -> AdjointT f g w b
fmap a -> b
f (AdjointT f (w (g a))
g) = forall (f :: * -> *) (g :: * -> *) (w :: * -> *) a.
f (w (g a)) -> AdjointT f g w a
AdjointT forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f)) f (w (g a))
g
a
b <$ :: forall a b. a -> AdjointT f g w b -> AdjointT f g w a
<$ (AdjointT f (w (g b))
g) = forall (f :: * -> *) (g :: * -> *) (w :: * -> *) a.
f (w (g a)) -> AdjointT f g w a
AdjointT forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a
b forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$)) f (w (g b))
g
instance (Adjunction f g, Extend w) => Extend (AdjointT f g w) where
extended :: forall a b.
(AdjointT f g w a -> b) -> AdjointT f g w a -> AdjointT f g w b
extended AdjointT f g w a -> b
f (AdjointT f (w (g a))
m) = forall (f :: * -> *) (g :: * -> *) (w :: * -> *) a.
f (w (g a)) -> AdjointT f g w a
AdjointT forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (w :: * -> *) a b. Extend w => (w a -> b) -> w a -> w b
extended forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) (u :: * -> *) a b.
Adjunction f u =>
(f a -> b) -> a -> u b
leftAdjunct (AdjointT f g w a -> b
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) (g :: * -> *) (w :: * -> *) a.
f (w (g a)) -> AdjointT f g w a
AdjointT)) f (w (g a))
m
instance (Adjunction f g, Comonad w) => Comonad (AdjointT f g w) where
extend :: forall a b.
(AdjointT f g w a -> b) -> AdjointT f g w a -> AdjointT f g w b
extend AdjointT f g w a -> b
f (AdjointT f (w (g a))
m) = forall (f :: * -> *) (g :: * -> *) (w :: * -> *) a.
f (w (g a)) -> AdjointT f g w a
AdjointT forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (w :: * -> *) a b. Comonad w => (w a -> b) -> w a -> w b
extend forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) (u :: * -> *) a b.
Adjunction f u =>
(f a -> b) -> a -> u b
leftAdjunct (AdjointT f g w a -> b
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) (g :: * -> *) (w :: * -> *) a.
f (w (g a)) -> AdjointT f g w a
AdjointT)) f (w (g a))
m
extract :: forall a. AdjointT f g w a -> a
extract = forall (f :: * -> *) (u :: * -> *) a b.
Adjunction f u =>
(a -> u b) -> f a -> b
rightAdjunct forall (w :: * -> *) a. Comonad w => w a -> a
extract forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) (g :: * -> *) (w :: * -> *) a.
AdjointT f g w a -> f (w (g a))
runAdjointT
instance (Adjunction f g, Distributive g) => ComonadTrans (AdjointT f g) where
lower :: forall (w :: * -> *) a. Comonad w => AdjointT f g w a -> w a
lower = forall (f :: * -> *) (u :: * -> *) a.
Adjunction f u =>
f (u a) -> a
counit forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (g :: * -> *) (f :: * -> *) a.
(Distributive g, Functor f) =>
f (g a) -> g (f a)
distribute forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) (g :: * -> *) (w :: * -> *) a.
AdjointT f g w a -> f (w (g a))
runAdjointT