{-# LANGUAGE CPP #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE UndecidableInstances #-}
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
{-# LANGUAGE Trustworthy #-}
#endif
module Data.Functor.Contravariant.Yoneda
( Yoneda(..)
, liftYoneda, lowerYoneda
) where
import Data.Functor.Contravariant
import Data.Functor.Contravariant.Adjunction
import Data.Functor.Contravariant.Rep
newtype Yoneda f a = Yoneda { Yoneda f a -> forall r. (r -> a) -> f r
runYoneda :: forall r. (r -> a) -> f r }
liftYoneda :: Contravariant f => f a -> Yoneda f a
liftYoneda :: f a -> Yoneda f a
liftYoneda f a
fa = (forall r. (r -> a) -> f r) -> Yoneda f a
forall (f :: * -> *) a. (forall r. (r -> a) -> f r) -> Yoneda f a
Yoneda ((forall r. (r -> a) -> f r) -> Yoneda f a)
-> (forall r. (r -> a) -> f r) -> Yoneda f a
forall a b. (a -> b) -> a -> b
$ \r -> a
ra -> (r -> a) -> f a -> f r
forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
contramap r -> a
ra f a
fa
{-# INLINE liftYoneda #-}
lowerYoneda :: Yoneda f a -> f a
lowerYoneda :: Yoneda f a -> f a
lowerYoneda Yoneda f a
f = Yoneda f a -> (a -> a) -> f a
forall (f :: * -> *) a. Yoneda f a -> forall r. (r -> a) -> f r
runYoneda Yoneda f a
f a -> a
forall a. a -> a
id
{-# INLINE lowerYoneda #-}
instance Contravariant (Yoneda f) where
contramap :: (a -> b) -> Yoneda f b -> Yoneda f a
contramap a -> b
ab (Yoneda forall r. (r -> b) -> f r
m) = (forall r. (r -> a) -> f r) -> Yoneda f a
forall (f :: * -> *) a. (forall r. (r -> a) -> f r) -> Yoneda f a
Yoneda ((r -> b) -> f r
forall r. (r -> b) -> f r
m ((r -> b) -> f r) -> ((r -> a) -> r -> b) -> (r -> a) -> f r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> b) -> (r -> a) -> r -> b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
ab)
{-# INLINE contramap #-}
instance Representable f => Representable (Yoneda f) where
type Rep (Yoneda f) = Rep f
tabulate :: (a -> Rep (Yoneda f)) -> Yoneda f a
tabulate = f a -> Yoneda f a
forall (f :: * -> *) a. Contravariant f => f a -> Yoneda f a
liftYoneda (f a -> Yoneda f a)
-> ((a -> Rep f) -> f a) -> (a -> Rep f) -> Yoneda f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Rep f) -> f a
forall (f :: * -> *) a. Representable f => (a -> Rep f) -> f a
tabulate
{-# INLINE tabulate #-}
index :: Yoneda f a -> a -> Rep (Yoneda f)
index Yoneda f a
m a
a = f a -> a -> Rep f
forall (f :: * -> *) a. Representable f => f a -> a -> Rep f
index (Yoneda f a -> f a
forall (f :: * -> *) a. Yoneda f a -> f a
lowerYoneda Yoneda f a
m) a
a
{-# INLINE index #-}
contramapWithRep :: (b -> Either a (Rep (Yoneda f))) -> Yoneda f a -> Yoneda f b
contramapWithRep b -> Either a (Rep (Yoneda f))
beav = f b -> Yoneda f b
forall (f :: * -> *) a. Contravariant f => f a -> Yoneda f a
liftYoneda (f b -> Yoneda f b)
-> (Yoneda f a -> f b) -> Yoneda f a -> Yoneda f b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (b -> Either a (Rep f)) -> f a -> f b
forall (f :: * -> *) b a.
Representable f =>
(b -> Either a (Rep f)) -> f a -> f b
contramapWithRep b -> Either a (Rep f)
b -> Either a (Rep (Yoneda f))
beav (f a -> f b) -> (Yoneda f a -> f a) -> Yoneda f a -> f b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Yoneda f a -> f a
forall (f :: * -> *) a. Yoneda f a -> f a
lowerYoneda
{-# INLINE contramapWithRep #-}
instance Adjunction f g => Adjunction (Yoneda f) (Yoneda g) where
leftAdjunct :: (b -> Yoneda f a) -> a -> Yoneda g b
leftAdjunct b -> Yoneda f a
f = g b -> Yoneda g b
forall (f :: * -> *) a. Contravariant f => f a -> Yoneda f a
liftYoneda (g b -> Yoneda g b) -> (a -> g b) -> a -> Yoneda g b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (b -> f a) -> a -> g b
forall (f :: * -> *) (g :: * -> *) b a.
Adjunction f g =>
(b -> f a) -> a -> g b
leftAdjunct (Yoneda f a -> f a
forall (f :: * -> *) a. Yoneda f a -> f a
lowerYoneda (Yoneda f a -> f a) -> (b -> Yoneda f a) -> b -> f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> Yoneda f a
f)
{-# INLINE leftAdjunct #-}
rightAdjunct :: (a -> Yoneda g b) -> b -> Yoneda f a
rightAdjunct a -> Yoneda g b
f = f a -> Yoneda f a
forall (f :: * -> *) a. Contravariant f => f a -> Yoneda f a
liftYoneda (f a -> Yoneda f a) -> (b -> f a) -> b -> Yoneda f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> g b) -> b -> f a
forall (f :: * -> *) (g :: * -> *) a b.
Adjunction f g =>
(a -> g b) -> b -> f a
rightAdjunct (Yoneda g b -> g b
forall (f :: * -> *) a. Yoneda f a -> f a
lowerYoneda (Yoneda g b -> g b) -> (a -> Yoneda g b) -> a -> g b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Yoneda g b
f)
{-# INLINE rightAdjunct #-}