ekmett / adjunctions

Simple adjunctions
http://hackage.haskell.org/package/adjunctions
Other
44 stars 27 forks source link

Adjunction f u means f a is isomorphic to (a, Rep u) #22

Open Zemyla opened 8 years ago

Zemyla commented 8 years ago

There is an explicit isomorphism for this:

fromAdj :: Adjunction f u => f a -> (a, Rep u)
fromAdj = rightAdjunct (tabulate . (,))

toAdj :: Adjunction f u => a -> Rep u -> f a
toAdj = index . unit

And there should be a newtype wrapper, for instance named Adj, that works like Co in Data.Functor.Rep, and provides instances for Comonad, instances for Applicative and Monad when Rep u is a Monoid, etc. Also, there would be an Adjunction between Adj f and Co u, so that Co u has an Adjunction whenever u does.

Icelandjack commented 7 years ago

Did you mean something like this

newtype WrappedAdj :: (Type -> Type) -> (Type -> Type) -> (Type -> Type) where
  WrapAdj :: u a -> WrappedAdj f u a
  deriving Functor

instance Adjunction f u => Distributive (WrappedAdj f u) where
  distribute :: Functor g => g (WrappedAdj f u a) -> WrappedAdj f u (g a)
  distribute = distributeRep

instance Adjunction f u => Representable (WrappedAdj f u) where
  type Rep (WrappedAdj f u) = f ()

  index :: WrappedAdj f u a -> (f () -> a)
  index (WrapAdj ua) = indexAdjunction ua

  tabulate :: (f () -> a) -> WrappedAdj f u a
  tabulate f = WrapAdj (tabulateAdjunction f)
data    (:!) r b = b :! Rep r deriving (Functor)
newtype Arr  r b = Arr  (r b) deriving newtype (Functor, Representable)

instance Representable r => Distributive (Arr r) where
  distribute :: Functor f => f (Arr r a) -> Arr r (f a)
  distribute = distributeRep

instance Representable r => Adjunction ((:!) r) (Arr r) where
  unit :: a -> Arr r (r :! a)
  unit = Arr . tabulate . (:!)

  counit :: r :! Arr r a -> a
  counit (xs :! rep) = xs `index` rep