{-# LANGUAGE GADTs #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE Trustworthy #-}
-----------------------------------------------------------------------------
-- |
-- Copyright   :  (C) 2017 Edward Kmett
-- License     :  BSD-style (see the file LICENSE)
--
-- Maintainer  :  Edward Kmett <ekmett@gmail.com>
-- Stability   :  provisional
-- Portability :  Rank2Types, TFs
--
----------------------------------------------------------------------------
module Data.Profunctor.Yoneda
  ( Yoneda(..), extractYoneda, duplicateYoneda
  , Coyoneda(..), returnCoyoneda, joinCoyoneda
  ) where

import Control.Category
import Data.Coerce (Coercible, coerce)
import Data.Profunctor
import Data.Profunctor.Monad
import Data.Profunctor.Traversing
import Data.Profunctor.Unsafe
import Prelude hiding (id,(.))

--------------------------------------------------------------------------------
-- * Yoneda
--------------------------------------------------------------------------------

-- | This is the cofree profunctor given a data constructor of kind @* -> * -> *@
newtype Yoneda p a b = Yoneda { forall (p :: * -> * -> *) a b.
Yoneda p a b -> forall x y. (x -> a) -> (b -> y) -> p x y
runYoneda :: forall x y. (x -> a) -> (b -> y) -> p x y }

-- Yoneda is a comonad on |*| -> Nat(|*|,*), we don't need the profunctor constraint to extract or duplicate
-- |
-- @
-- 'projoin' '.' 'extractYoneda' ≡ 'id'
-- 'extractYoneda' '.' 'projoin' ≡ 'id'
-- 'projoin' ≡ 'extractYoneda'
-- @
extractYoneda :: Yoneda p a b -> p a b
extractYoneda :: forall (p :: * -> * -> *) a b. Yoneda p a b -> p a b
extractYoneda Yoneda p a b
p = forall (p :: * -> * -> *) a b.
Yoneda p a b -> forall x y. (x -> a) -> (b -> y) -> p x y
runYoneda Yoneda p a b
p forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id

-- |
-- @
-- 'projoin' '.' 'duplicateYoneda' ≡ 'id'
-- 'duplicateYoneda' '.' 'projoin' ≡ 'id'
-- 'duplicateYoneda' = 'proreturn'
-- @
duplicateYoneda :: Yoneda p a b -> Yoneda (Yoneda p) a b
duplicateYoneda :: forall (p :: * -> * -> *) a b.
Yoneda p a b -> Yoneda (Yoneda p) a b
duplicateYoneda Yoneda p a b
p = forall (p :: * -> * -> *) a b.
(forall x y. (x -> a) -> (b -> y) -> p x y) -> Yoneda p a b
Yoneda forall a b. (a -> b) -> a -> b
$ \x -> a
l b -> y
r -> forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap x -> a
l b -> y
r Yoneda p a b
p

instance Profunctor (Yoneda p) where
  dimap :: forall a b c d.
(a -> b) -> (c -> d) -> Yoneda p b c -> Yoneda p a d
dimap a -> b
l c -> d
r Yoneda p b c
p = forall (p :: * -> * -> *) a b.
(forall x y. (x -> a) -> (b -> y) -> p x y) -> Yoneda p a b
Yoneda forall a b. (a -> b) -> a -> b
$ \x -> a
l' d -> y
r' -> forall (p :: * -> * -> *) a b.
Yoneda p a b -> forall x y. (x -> a) -> (b -> y) -> p x y
runYoneda Yoneda p b c
p (a -> b
l forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. x -> a
l') (d -> y
r' forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. c -> d
r)
  {-# INLINE dimap #-}
  lmap :: forall a b c. (a -> b) -> Yoneda p b c -> Yoneda p a c
lmap a -> b
l Yoneda p b c
p = forall (p :: * -> * -> *) a b.
(forall x y. (x -> a) -> (b -> y) -> p x y) -> Yoneda p a b
Yoneda forall a b. (a -> b) -> a -> b
$ \x -> a
l' c -> y
r -> forall (p :: * -> * -> *) a b.
Yoneda p a b -> forall x y. (x -> a) -> (b -> y) -> p x y
runYoneda Yoneda p b c
p (a -> b
l forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. x -> a
l') c -> y
r
  {-# INLINE lmap #-}
  rmap :: forall b c a. (b -> c) -> Yoneda p a b -> Yoneda p a c
rmap b -> c
r Yoneda p a b
p = forall (p :: * -> * -> *) a b.
(forall x y. (x -> a) -> (b -> y) -> p x y) -> Yoneda p a b
Yoneda forall a b. (a -> b) -> a -> b
$ \x -> a
l c -> y
r' -> forall (p :: * -> * -> *) a b.
Yoneda p a b -> forall x y. (x -> a) -> (b -> y) -> p x y
runYoneda Yoneda p a b
p x -> a
l (c -> y
r' forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. b -> c
r)
  {-# INLINE rmap #-}
  .# :: forall a b c (q :: * -> * -> *).
Coercible b a =>
Yoneda p b c -> q a b -> Yoneda p a c
(.#) Yoneda p b c
p q a b
_ = coerce :: forall a b. Coercible a b => a -> b
coerce Yoneda p b c
p
  {-# INLINE (.#) #-}
  #. :: forall a b c (q :: * -> * -> *).
Coercible c b =>
q b c -> Yoneda p a b -> Yoneda p a c
(#.) q b c
_ = coerce :: forall a b. Coercible a b => a -> b
coerce (\b
x -> b
x :: b) :: forall a b. Coercible b a => a -> b
  {-# INLINE (#.) #-}

instance Functor (Yoneda p a) where
  fmap :: forall a b. (a -> b) -> Yoneda p a a -> Yoneda p a b
fmap a -> b
f Yoneda p a a
p = forall (p :: * -> * -> *) a b.
(forall x y. (x -> a) -> (b -> y) -> p x y) -> Yoneda p a b
Yoneda forall a b. (a -> b) -> a -> b
$ \x -> a
l b -> y
r -> forall (p :: * -> * -> *) a b.
Yoneda p a b -> forall x y. (x -> a) -> (b -> y) -> p x y
runYoneda Yoneda p a a
p x -> a
l (b -> y
r forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. a -> b
f)
  {-# INLINE fmap #-}

instance ProfunctorFunctor Yoneda where
  promap :: forall (p :: * -> * -> *) (q :: * -> * -> *).
Profunctor p =>
(p :-> q) -> Yoneda p :-> Yoneda q
promap p :-> q
f Yoneda p a b
p = forall (p :: * -> * -> *) a b.
(forall x y. (x -> a) -> (b -> y) -> p x y) -> Yoneda p a b
Yoneda forall a b. (a -> b) -> a -> b
$ \x -> a
l b -> y
r -> p :-> q
f (forall (p :: * -> * -> *) a b.
Yoneda p a b -> forall x y. (x -> a) -> (b -> y) -> p x y
runYoneda Yoneda p a b
p x -> a
l b -> y
r)
  {-# INLINE promap #-}

instance ProfunctorComonad Yoneda where
  proextract :: forall (p :: * -> * -> *). Profunctor p => Yoneda p :-> p
proextract Yoneda p a b
p = forall (p :: * -> * -> *) a b.
Yoneda p a b -> forall x y. (x -> a) -> (b -> y) -> p x y
runYoneda Yoneda p a b
p forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id
  {-# INLINE proextract #-}
  produplicate :: forall (p :: * -> * -> *).
Profunctor p =>
Yoneda p :-> Yoneda (Yoneda p)
produplicate Yoneda p a b
p = forall (p :: * -> * -> *) a b.
(forall x y. (x -> a) -> (b -> y) -> p x y) -> Yoneda p a b
Yoneda forall a b. (a -> b) -> a -> b
$ \x -> a
l b -> y
r -> forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap x -> a
l b -> y
r Yoneda p a b
p
  {-# INLINE produplicate #-}

instance ProfunctorMonad Yoneda where
  proreturn :: forall (p :: * -> * -> *). Profunctor p => p :-> Yoneda p
proreturn p a b
p = forall (p :: * -> * -> *) a b.
(forall x y. (x -> a) -> (b -> y) -> p x y) -> Yoneda p a b
Yoneda forall a b. (a -> b) -> a -> b
$ \x -> a
l b -> y
r -> forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap x -> a
l b -> y
r p a b
p
  {-# INLINE proreturn #-}
  projoin :: forall (p :: * -> * -> *).
Profunctor p =>
Yoneda (Yoneda p) :-> Yoneda p
projoin Yoneda (Yoneda p) a b
p = forall (p :: * -> * -> *) a b.
Yoneda p a b -> forall x y. (x -> a) -> (b -> y) -> p x y
runYoneda Yoneda (Yoneda p) a b
p forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id
  {-# INLINE projoin #-}

instance (Category p, Profunctor p) => Category (Yoneda p) where
  id :: forall a. Yoneda p a a
id = forall (p :: * -> * -> *) a b.
(forall x y. (x -> a) -> (b -> y) -> p x y) -> Yoneda p a b
Yoneda forall a b. (a -> b) -> a -> b
$ \x -> a
l a -> y
r -> forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap x -> a
l a -> y
r forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id
  {-# INLINE id #-}
  Yoneda p b c
p . :: forall b c a. Yoneda p b c -> Yoneda p a b -> Yoneda p a c
. Yoneda p a b
q = forall (p :: * -> * -> *) a b.
(forall x y. (x -> a) -> (b -> y) -> p x y) -> Yoneda p a b
Yoneda forall a b. (a -> b) -> a -> b
$ \ x -> a
l c -> y
r -> forall (p :: * -> * -> *) a b.
Yoneda p a b -> forall x y. (x -> a) -> (b -> y) -> p x y
runYoneda Yoneda p b c
p forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id c -> y
r forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a b.
Yoneda p a b -> forall x y. (x -> a) -> (b -> y) -> p x y
runYoneda Yoneda p a b
q x -> a
l forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id
  {-# INLINE (.) #-}

instance Strong p => Strong (Yoneda p) where
  first' :: forall a b c. Yoneda p a b -> Yoneda p (a, c) (b, c)
first' = forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
(ProfunctorMonad t, Profunctor p) =>
p :-> t p
proreturn forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a b c.
Strong p =>
p a b -> p (a, c) (b, c)
first' forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a b. Yoneda p a b -> p a b
extractYoneda
  {-# INLINE first' #-}
  second' :: forall a b c. Yoneda p a b -> Yoneda p (c, a) (c, b)
second' = forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
(ProfunctorMonad t, Profunctor p) =>
p :-> t p
proreturn forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a b c.
Strong p =>
p a b -> p (c, a) (c, b)
second' forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a b. Yoneda p a b -> p a b
extractYoneda
  {-# INLINE second' #-}

instance Choice p => Choice (Yoneda p) where
  left' :: forall a b c. Yoneda p a b -> Yoneda p (Either a c) (Either b c)
left' = forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
(ProfunctorMonad t, Profunctor p) =>
p :-> t p
proreturn forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a b c.
Choice p =>
p a b -> p (Either a c) (Either b c)
left' forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a b. Yoneda p a b -> p a b
extractYoneda
  {-# INLINE left' #-}
  right' :: forall a b c. Yoneda p a b -> Yoneda p (Either c a) (Either c b)
right' = forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
(ProfunctorMonad t, Profunctor p) =>
p :-> t p
proreturn forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a b c.
Choice p =>
p a b -> p (Either c a) (Either c b)
right' forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a b. Yoneda p a b -> p a b
extractYoneda
  {-# INLINE right' #-}

instance Costrong p => Costrong (Yoneda p) where
  unfirst :: forall a d b. Yoneda p (a, d) (b, d) -> Yoneda p a b
unfirst = forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
(ProfunctorMonad t, Profunctor p) =>
p :-> t p
proreturn forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a d b.
Costrong p =>
p (a, d) (b, d) -> p a b
unfirst forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a b. Yoneda p a b -> p a b
extractYoneda
  {-# INLINE unfirst #-}
  unsecond :: forall d a b. Yoneda p (d, a) (d, b) -> Yoneda p a b
unsecond = forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
(ProfunctorMonad t, Profunctor p) =>
p :-> t p
proreturn forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) d a b.
Costrong p =>
p (d, a) (d, b) -> p a b
unsecond forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a b. Yoneda p a b -> p a b
extractYoneda
  {-# INLINE unsecond #-}

instance Cochoice p => Cochoice (Yoneda p) where
  unleft :: forall a d b. Yoneda p (Either a d) (Either b d) -> Yoneda p a b
unleft = forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
(ProfunctorMonad t, Profunctor p) =>
p :-> t p
proreturn forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a d b.
Cochoice p =>
p (Either a d) (Either b d) -> p a b
unleft forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a b. Yoneda p a b -> p a b
extractYoneda
  {-# INLINE unleft #-}
  unright :: forall d a b. Yoneda p (Either d a) (Either d b) -> Yoneda p a b
unright = forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
(ProfunctorMonad t, Profunctor p) =>
p :-> t p
proreturn forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) d a b.
Cochoice p =>
p (Either d a) (Either d b) -> p a b
unright forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a b. Yoneda p a b -> p a b
extractYoneda
  {-# INLINE unright #-}

instance Closed p => Closed (Yoneda p) where
  closed :: forall a b x. Yoneda p a b -> Yoneda p (x -> a) (x -> b)
closed = forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
(ProfunctorMonad t, Profunctor p) =>
p :-> t p
proreturn forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a b x.
Closed p =>
p a b -> p (x -> a) (x -> b)
closed forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a b. Yoneda p a b -> p a b
extractYoneda
  {-# INLINE closed #-}

instance Mapping p => Mapping (Yoneda p) where
  map' :: forall (f :: * -> *) a b.
Functor f =>
Yoneda p a b -> Yoneda p (f a) (f b)
map' = forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
(ProfunctorMonad t, Profunctor p) =>
p :-> t p
proreturn forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) (f :: * -> *) a b.
(Mapping p, Functor f) =>
p a b -> p (f a) (f b)
map' forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a b. Yoneda p a b -> p a b
extractYoneda
  {-# INLINE map' #-}

instance Traversing p => Traversing (Yoneda p) where
  traverse' :: forall (f :: * -> *) a b.
Traversable f =>
Yoneda p a b -> Yoneda p (f a) (f b)
traverse' = forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
(ProfunctorMonad t, Profunctor p) =>
p :-> t p
proreturn forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) (f :: * -> *) a b.
(Traversing p, Traversable f) =>
p a b -> p (f a) (f b)
traverse' forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a b. Yoneda p a b -> p a b
extractYoneda
  {-# INLINE traverse' #-}
  wander :: forall a b s t.
(forall (f :: * -> *). Applicative f => (a -> f b) -> s -> f t)
-> Yoneda p a b -> Yoneda p s t
wander forall (f :: * -> *). Applicative f => (a -> f b) -> s -> f t
f = forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
(ProfunctorMonad t, Profunctor p) =>
p :-> t p
proreturn forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a b s t.
Traversing p =>
(forall (f :: * -> *). Applicative f => (a -> f b) -> s -> f t)
-> p a b -> p s t
wander forall (f :: * -> *). Applicative f => (a -> f b) -> s -> f t
f forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a b. Yoneda p a b -> p a b
extractYoneda
  {-# INLINE wander #-}

--------------------------------------------------------------------------------
-- * Coyoneda
--------------------------------------------------------------------------------

data Coyoneda p a b where
  Coyoneda :: (a -> x) -> (y -> b) -> p x y -> Coyoneda p a b

-- Coyoneda is a Monad on |*| -> Nat(|*|,*), we don't need the profunctor constraint to extract or duplicate

-- |
-- @
-- 'returnCoyoneda' '.' 'proextract' ≡ 'id'
-- 'proextract' '.' 'returnCoyoneda' ≡ 'id'
-- 'produplicate' ≡ 'returnCoyoneda'
-- @
returnCoyoneda :: p a b -> Coyoneda p a b
returnCoyoneda :: forall (p :: * -> * -> *) a b. p a b -> Coyoneda p a b
returnCoyoneda = forall a x y b (p :: * -> * -> *).
(a -> x) -> (y -> b) -> p x y -> Coyoneda p a b
Coyoneda forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id

-- |
-- @
-- 'joinCoyoneda' '.' 'produplicate' ≡ 'id'
-- 'produplicate' '.' 'joinCoyoneda' ≡ 'id'
-- 'joinCoyoneda' ≡ 'proextract'
-- @
joinCoyoneda :: Coyoneda (Coyoneda p) a b -> Coyoneda p a b
joinCoyoneda :: forall (p :: * -> * -> *) a b.
Coyoneda (Coyoneda p) a b -> Coyoneda p a b
joinCoyoneda (Coyoneda a -> x
l y -> b
r Coyoneda p x y
p) = forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap a -> x
l y -> b
r Coyoneda p x y
p

instance Functor (Coyoneda p a) where
  fmap :: forall a b. (a -> b) -> Coyoneda p a a -> Coyoneda p a b
fmap a -> b
f (Coyoneda a -> x
l y -> a
r' p x y
p) = forall a x y b (p :: * -> * -> *).
(a -> x) -> (y -> b) -> p x y -> Coyoneda p a b
Coyoneda a -> x
l (a -> b
f forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. y -> a
r') p x y
p

instance Profunctor (Coyoneda p) where
  dimap :: forall a b c d.
(a -> b) -> (c -> d) -> Coyoneda p b c -> Coyoneda p a d
dimap a -> b
l c -> d
r (Coyoneda b -> x
l' y -> c
r' p x y
p) = forall a x y b (p :: * -> * -> *).
(a -> x) -> (y -> b) -> p x y -> Coyoneda p a b
Coyoneda (b -> x
l' forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. a -> b
l) (c -> d
r forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. y -> c
r') p x y
p
  {-# INLINE dimap #-}
  lmap :: forall a b c. (a -> b) -> Coyoneda p b c -> Coyoneda p a c
lmap a -> b
l (Coyoneda b -> x
l' y -> c
r p x y
p) = forall a x y b (p :: * -> * -> *).
(a -> x) -> (y -> b) -> p x y -> Coyoneda p a b
Coyoneda (b -> x
l' forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. a -> b
l) y -> c
r p x y
p
  {-# INLINE lmap #-}
  rmap :: forall b c a. (b -> c) -> Coyoneda p a b -> Coyoneda p a c
rmap b -> c
r (Coyoneda a -> x
l y -> b
r' p x y
p) = forall a x y b (p :: * -> * -> *).
(a -> x) -> (y -> b) -> p x y -> Coyoneda p a b
Coyoneda a -> x
l (b -> c
r forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. y -> b
r') p x y
p
  {-# INLINE rmap #-}
  .# :: forall a b c (q :: * -> * -> *).
Coercible b a =>
Coyoneda p b c -> q a b -> Coyoneda p a c
(.#) Coyoneda p b c
p q a b
_ = coerce :: forall a b. Coercible a b => a -> b
coerce Coyoneda p b c
p
  {-# INLINE (.#) #-}
  #. :: forall a b c (q :: * -> * -> *).
Coercible c b =>
q b c -> Coyoneda p a b -> Coyoneda p a c
(#.) q b c
_ = coerce :: forall a b. Coercible a b => a -> b
coerce (\b
x -> b
x :: b) :: forall a b. Coercible b a => a -> b
  {-# INLINE (#.) #-}

instance ProfunctorFunctor Coyoneda where
  promap :: forall (p :: * -> * -> *) (q :: * -> * -> *).
Profunctor p =>
(p :-> q) -> Coyoneda p :-> Coyoneda q
promap p :-> q
f (Coyoneda a -> x
l y -> b
r p x y
p) = forall a x y b (p :: * -> * -> *).
(a -> x) -> (y -> b) -> p x y -> Coyoneda p a b
Coyoneda a -> x
l y -> b
r (p :-> q
f p x y
p)
  {-# INLINE promap #-}

instance ProfunctorComonad Coyoneda where
  proextract :: forall (p :: * -> * -> *). Profunctor p => Coyoneda p :-> p
proextract (Coyoneda a -> x
l y -> b
r p x y
p) = forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap a -> x
l y -> b
r p x y
p
  {-# INLINE proextract #-}
  produplicate :: forall (p :: * -> * -> *).
Profunctor p =>
Coyoneda p :-> Coyoneda (Coyoneda p)
produplicate = forall a x y b (p :: * -> * -> *).
(a -> x) -> (y -> b) -> p x y -> Coyoneda p a b
Coyoneda forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id
  {-# INLINE produplicate #-}

instance ProfunctorMonad Coyoneda where
  proreturn :: forall (p :: * -> * -> *). Profunctor p => p :-> Coyoneda p
proreturn = forall (p :: * -> * -> *) a b. p a b -> Coyoneda p a b
returnCoyoneda
  {-# INLINE proreturn #-}
  projoin :: forall (p :: * -> * -> *).
Profunctor p =>
Coyoneda (Coyoneda p) :-> Coyoneda p
projoin = forall (p :: * -> * -> *) a b.
Coyoneda (Coyoneda p) a b -> Coyoneda p a b
joinCoyoneda
  {-# INLINE projoin #-}

instance (Category p, Profunctor p) => Category (Coyoneda p) where
  id :: forall a. Coyoneda p a a
id = forall a x y b (p :: * -> * -> *).
(a -> x) -> (y -> b) -> p x y -> Coyoneda p a b
Coyoneda forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id
  {-# INLINE id #-}
  Coyoneda b -> x
lp y -> c
rp p x y
p . :: forall b c a. Coyoneda p b c -> Coyoneda p a b -> Coyoneda p a c
. Coyoneda a -> x
lq y -> b
rq p x y
q = forall a x y b (p :: * -> * -> *).
(a -> x) -> (y -> b) -> p x y -> Coyoneda p a b
Coyoneda a -> x
lq y -> c
rp (p x y
p forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) b c a.
Profunctor p =>
(b -> c) -> p a b -> p a c
rmap (b -> x
lp forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. y -> b
rq) p x y
q)
  {-# INLINE (.) #-}

instance Strong p => Strong (Coyoneda p) where
  first' :: forall a b c. Coyoneda p a b -> Coyoneda p (a, c) (b, c)
first' = forall (p :: * -> * -> *) a b. p a b -> Coyoneda p a b
returnCoyoneda forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a b c.
Strong p =>
p a b -> p (a, c) (b, c)
first' forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
(ProfunctorComonad t, Profunctor p) =>
t p :-> p
proextract
  {-# INLINE first' #-}
  second' :: forall a b c. Coyoneda p a b -> Coyoneda p (c, a) (c, b)
second' = forall (p :: * -> * -> *) a b. p a b -> Coyoneda p a b
returnCoyoneda forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a b c.
Strong p =>
p a b -> p (c, a) (c, b)
second' forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
(ProfunctorComonad t, Profunctor p) =>
t p :-> p
proextract
  {-# INLINE second' #-}

instance Choice p => Choice (Coyoneda p) where
  left' :: forall a b c.
Coyoneda p a b -> Coyoneda p (Either a c) (Either b c)
left' = forall (p :: * -> * -> *) a b. p a b -> Coyoneda p a b
returnCoyoneda forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a b c.
Choice p =>
p a b -> p (Either a c) (Either b c)
left' forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
(ProfunctorComonad t, Profunctor p) =>
t p :-> p
proextract
  {-# INLINE left' #-}
  right' :: forall a b c.
Coyoneda p a b -> Coyoneda p (Either c a) (Either c b)
right' = forall (p :: * -> * -> *) a b. p a b -> Coyoneda p a b
returnCoyoneda forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a b c.
Choice p =>
p a b -> p (Either c a) (Either c b)
right' forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
(ProfunctorComonad t, Profunctor p) =>
t p :-> p
proextract
  {-# INLINE right' #-}

instance Costrong p => Costrong (Coyoneda p) where
  unfirst :: forall a d b. Coyoneda p (a, d) (b, d) -> Coyoneda p a b
unfirst = forall (p :: * -> * -> *) a b. p a b -> Coyoneda p a b
returnCoyoneda forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a d b.
Costrong p =>
p (a, d) (b, d) -> p a b
unfirst forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
(ProfunctorComonad t, Profunctor p) =>
t p :-> p
proextract
  {-# INLINE unfirst #-}
  unsecond :: forall d a b. Coyoneda p (d, a) (d, b) -> Coyoneda p a b
unsecond = forall (p :: * -> * -> *) a b. p a b -> Coyoneda p a b
returnCoyoneda forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) d a b.
Costrong p =>
p (d, a) (d, b) -> p a b
unsecond forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
(ProfunctorComonad t, Profunctor p) =>
t p :-> p
proextract
  {-# INLINE unsecond #-}

instance Cochoice p => Cochoice (Coyoneda p) where
  unleft :: forall a d b.
Coyoneda p (Either a d) (Either b d) -> Coyoneda p a b
unleft = forall (p :: * -> * -> *) a b. p a b -> Coyoneda p a b
returnCoyoneda forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a d b.
Cochoice p =>
p (Either a d) (Either b d) -> p a b
unleft forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
(ProfunctorComonad t, Profunctor p) =>
t p :-> p
proextract
  {-# INLINE unleft #-}
  unright :: forall d a b.
Coyoneda p (Either d a) (Either d b) -> Coyoneda p a b
unright = forall (p :: * -> * -> *) a b. p a b -> Coyoneda p a b
returnCoyoneda forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) d a b.
Cochoice p =>
p (Either d a) (Either d b) -> p a b
unright forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
(ProfunctorComonad t, Profunctor p) =>
t p :-> p
proextract
  {-# INLINE unright #-}

instance Closed p => Closed (Coyoneda p) where
  closed :: forall a b x. Coyoneda p a b -> Coyoneda p (x -> a) (x -> b)
closed = forall (p :: * -> * -> *) a b. p a b -> Coyoneda p a b
returnCoyoneda forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a b x.
Closed p =>
p a b -> p (x -> a) (x -> b)
closed forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
(ProfunctorComonad t, Profunctor p) =>
t p :-> p
proextract
  {-# INLINE closed #-}

instance Mapping p => Mapping (Coyoneda p) where
  map' :: forall (f :: * -> *) a b.
Functor f =>
Coyoneda p a b -> Coyoneda p (f a) (f b)
map' = forall (p :: * -> * -> *) a b. p a b -> Coyoneda p a b
returnCoyoneda forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) (f :: * -> *) a b.
(Mapping p, Functor f) =>
p a b -> p (f a) (f b)
map' forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
(ProfunctorComonad t, Profunctor p) =>
t p :-> p
proextract
  {-# INLINE map' #-}

instance Traversing p => Traversing (Coyoneda p) where
  traverse' :: forall (f :: * -> *) a b.
Traversable f =>
Coyoneda p a b -> Coyoneda p (f a) (f b)
traverse' = forall (p :: * -> * -> *) a b. p a b -> Coyoneda p a b
returnCoyoneda forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) (f :: * -> *) a b.
(Traversing p, Traversable f) =>
p a b -> p (f a) (f b)
traverse' forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
(ProfunctorComonad t, Profunctor p) =>
t p :-> p
proextract
  {-# INLINE traverse' #-}
  wander :: forall a b s t.
(forall (f :: * -> *). Applicative f => (a -> f b) -> s -> f t)
-> Coyoneda p a b -> Coyoneda p s t
wander forall (f :: * -> *). Applicative f => (a -> f b) -> s -> f t
f = forall (p :: * -> * -> *) a b. p a b -> Coyoneda p a b
returnCoyoneda forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (p :: * -> * -> *) a b s t.
Traversing p =>
(forall (f :: * -> *). Applicative f => (a -> f b) -> s -> f t)
-> p a b -> p s t
wander forall (f :: * -> *). Applicative f => (a -> f b) -> s -> f t
f forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
(ProfunctorComonad t, Profunctor p) =>
t p :-> p
proextract
  {-# INLINE wander #-}