#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702
#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 { runYoneda :: forall r. (r -> a) -> f r }
liftYoneda :: Contravariant f => f a -> Yoneda f a
liftYoneda fa = Yoneda $ \ra -> contramap ra fa
lowerYoneda :: Yoneda f a -> f a
lowerYoneda f = runYoneda f id
instance Contravariant (Yoneda f) where
  contramap ab (Yoneda m) = Yoneda (m . fmap ab)
  
instance Representable f => Representable (Yoneda f) where
  type Rep (Yoneda f) = Rep f
  tabulate = liftYoneda . tabulate
  
  index m a = index (lowerYoneda m) a
  
  contramapWithRep beav = liftYoneda . contramapWithRep beav . lowerYoneda
  
instance Adjunction f g => Adjunction (Yoneda f) (Yoneda g) where
  leftAdjunct f = liftYoneda . leftAdjunct (lowerYoneda . f)
  
  rightAdjunct f = liftYoneda . rightAdjunct (lowerYoneda . f)