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