    {-# 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 = Yoneda p a b -> forall x y. (x -> a) -> (b -> y) -> p x y
    forall (p :: * -> * -> *) a b.
    Yoneda p a b -> forall x y. (x -> a) -> (b -> y) -> p x y
    runYoneda Yoneda p a b
    p a -> a
    forall a. a -> a
    forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
    id b -> b
    forall a. a -> a
    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 x y. (x -> a) -> (b -> y) -> Yoneda p x y)
    -> Yoneda (Yoneda p) a b
    forall (p :: * -> * -> *) a b.
    (forall x y. (x -> a) -> (b -> y) -> p x y) -> Yoneda p a b
    Yoneda ((forall x y. (x -> a) -> (b -> y) -> Yoneda p x y)
     -> Yoneda (Yoneda p) a b)
    -> (forall x y. (x -> a) -> (b -> y) -> Yoneda p x y)
    -> Yoneda (Yoneda p) a b
    forall a b. (a -> b) -> a -> b
    $ \x -> a
    l b -> y
    r -> (x -> a) -> (b -> y) -> Yoneda p a b -> Yoneda p x y
    forall a b c d.
    (a -> b) -> (c -> d) -> Yoneda p b c -> Yoneda p a d
    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 x y. (x -> a) -> (d -> y) -> p x y) -> Yoneda p a d
    forall (p :: * -> * -> *) a b.
    (forall x y. (x -> a) -> (b -> y) -> p x y) -> Yoneda p a b
    Yoneda ((forall x y. (x -> a) -> (d -> y) -> p x y) -> Yoneda p a d)
    -> (forall x y. (x -> a) -> (d -> y) -> p x y) -> Yoneda p a d
    forall a b. (a -> b) -> a -> b
    $ \x -> a
    l' d -> y
    r' -> Yoneda p b c -> forall x y. (x -> b) -> (c -> y) -> p x y
    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 (a -> b) -> (x -> a) -> x -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    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' (d -> y) -> (c -> d) -> c -> y
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    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 x y. (x -> a) -> (c -> y) -> p x y) -> Yoneda p a c
    forall (p :: * -> * -> *) a b.
    (forall x y. (x -> a) -> (b -> y) -> p x y) -> Yoneda p a b
    Yoneda ((forall x y. (x -> a) -> (c -> y) -> p x y) -> Yoneda p a c)
    -> (forall x y. (x -> a) -> (c -> y) -> p x y) -> Yoneda p a c
    forall a b. (a -> b) -> a -> b
    $ \x -> a
    l' c -> y
    r -> Yoneda p b c -> forall x y. (x -> b) -> (c -> y) -> p x y
    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 (a -> b) -> (x -> a) -> x -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    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 x y. (x -> a) -> (c -> y) -> p x y) -> Yoneda p a c
    forall (p :: * -> * -> *) a b.
    (forall x y. (x -> a) -> (b -> y) -> p x y) -> Yoneda p a b
    Yoneda ((forall x y. (x -> a) -> (c -> y) -> p x y) -> Yoneda p a c)
    -> (forall x y. (x -> a) -> (c -> y) -> p x y) -> Yoneda p a c
    forall a b. (a -> b) -> a -> b
    $ \x -> a
    l c -> y
    r' -> Yoneda p a b -> forall x y. (x -> a) -> (b -> y) -> p x y
    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' (c -> y) -> (b -> c) -> b -> y
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    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
    _ = Yoneda p b c -> Yoneda p a c
    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
    _ = (b -> b) -> a -> b
    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 x y. (x -> a) -> (b -> y) -> p x y) -> Yoneda p a b
    forall (p :: * -> * -> *) a b.
    (forall x y. (x -> a) -> (b -> y) -> p x y) -> Yoneda p a b
    Yoneda ((forall x y. (x -> a) -> (b -> y) -> p x y) -> Yoneda p a b)
    -> (forall x y. (x -> a) -> (b -> y) -> p x y) -> Yoneda p a b
    forall a b. (a -> b) -> a -> b
    $ \x -> a
    l b -> y
    r -> Yoneda p a a -> forall x y. (x -> a) -> (a -> y) -> p x y
    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 (b -> y) -> (a -> b) -> a -> y
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    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 x y. (x -> a) -> (b -> y) -> q x y) -> Yoneda q a b
    forall (p :: * -> * -> *) a b.
    (forall x y. (x -> a) -> (b -> y) -> p x y) -> Yoneda p a b
    Yoneda ((forall x y. (x -> a) -> (b -> y) -> q x y) -> Yoneda q a b)
    -> (forall x y. (x -> a) -> (b -> y) -> q x y) -> Yoneda q a b
    forall a b. (a -> b) -> a -> b
    $ \x -> a
    l b -> y
    r -> p x y -> q x y
    p :-> q
    f (Yoneda p a b -> forall x y. (x -> a) -> (b -> y) -> p x y
    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 = Yoneda p a b -> forall x y. (x -> a) -> (b -> y) -> p x y
    forall (p :: * -> * -> *) a b.
    Yoneda p a b -> forall x y. (x -> a) -> (b -> y) -> p x y
    runYoneda Yoneda p a b
    p a -> a
    forall a. a -> a
    forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
    id b -> b
    forall a. a -> a
    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 x y. (x -> a) -> (b -> y) -> Yoneda p x y)
    -> Yoneda (Yoneda p) a b
    forall (p :: * -> * -> *) a b.
    (forall x y. (x -> a) -> (b -> y) -> p x y) -> Yoneda p a b
    Yoneda ((forall x y. (x -> a) -> (b -> y) -> Yoneda p x y)
     -> Yoneda (Yoneda p) a b)
    -> (forall x y. (x -> a) -> (b -> y) -> Yoneda p x y)
    -> Yoneda (Yoneda p) a b
    forall a b. (a -> b) -> a -> b
    $ \x -> a
    l b -> y
    r -> (x -> a) -> (b -> y) -> Yoneda p a b -> Yoneda p x y
    forall a b c d.
    (a -> b) -> (c -> d) -> Yoneda p b c -> Yoneda p a d
    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 x y. (x -> a) -> (b -> y) -> p x y) -> Yoneda p a b
    forall (p :: * -> * -> *) a b.
    (forall x y. (x -> a) -> (b -> y) -> p x y) -> Yoneda p a b
    Yoneda ((forall x y. (x -> a) -> (b -> y) -> p x y) -> Yoneda p a b)
    -> (forall x y. (x -> a) -> (b -> y) -> p x y) -> Yoneda p a b
    forall a b. (a -> b) -> a -> b
    $ \x -> a
    l b -> y
    r -> (x -> a) -> (b -> y) -> p a b -> p x y
    forall a b c d. (a -> b) -> (c -> d) -> p b c -> p a d
    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 = Yoneda (Yoneda p) a b
    -> forall x y. (x -> a) -> (b -> y) -> Yoneda p x y
    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 a -> a
    forall a. a -> a
    forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
    id b -> b
    forall a. a -> a
    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 x y. (x -> a) -> (a -> y) -> p x y) -> Yoneda p a a
    forall (p :: * -> * -> *) a b.
    (forall x y. (x -> a) -> (b -> y) -> p x y) -> Yoneda p a b
    Yoneda ((forall x y. (x -> a) -> (a -> y) -> p x y) -> Yoneda p a a)
    -> (forall x y. (x -> a) -> (a -> y) -> p x y) -> Yoneda p a a
    forall a b. (a -> b) -> a -> b
    $ \x -> a
    l a -> y
    r -> (x -> a) -> (a -> y) -> p a a -> p x y
    forall a b c d. (a -> b) -> (c -> d) -> p b c -> p a d
    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 p a a
    forall a. p a a
    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 x y. (x -> a) -> (c -> y) -> p x y) -> Yoneda p a c
    forall (p :: * -> * -> *) a b.
    (forall x y. (x -> a) -> (b -> y) -> p x y) -> Yoneda p a b
    Yoneda ((forall x y. (x -> a) -> (c -> y) -> p x y) -> Yoneda p a c)
    -> (forall x y. (x -> a) -> (c -> y) -> p x y) -> Yoneda p a c
    forall a b. (a -> b) -> a -> b
    $ \ x -> a
    l c -> y
    r -> Yoneda p b c -> forall x y. (x -> b) -> (c -> y) -> p x y
    forall (p :: * -> * -> *) a b.
    Yoneda p a b -> forall x y. (x -> a) -> (b -> y) -> p x y
    runYoneda Yoneda p b c
    p b -> b
    forall a. a -> a
    forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
    id c -> y
    r p b y -> p x b -> p x y
    forall b c a. p b c -> p a b -> p a c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Yoneda p a b -> forall x y. (x -> a) -> (b -> y) -> p x y
    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 b -> b
    forall a. a -> a
    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' = p (a, c) (b, c) -> Yoneda p (a, c) (b, c)
    p :-> Yoneda p
    forall (p :: * -> * -> *). Profunctor p => p :-> Yoneda p
    forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
    (ProfunctorMonad t, Profunctor p) =>
    p :-> t p
    proreturn (p (a, c) (b, c) -> Yoneda p (a, c) (b, c))
    -> (Yoneda p a b -> p (a, c) (b, c))
    -> Yoneda p a b
    -> Yoneda p (a, c) (b, c)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . p a b -> p (a, c) (b, c)
    forall a b c. p a b -> p (a, c) (b, c)
    forall (p :: * -> * -> *) a b c.
    Strong p =>
    p a b -> p (a, c) (b, c)
    first' (p a b -> p (a, c) (b, c))
    -> (Yoneda p a b -> p a b) -> Yoneda p a b -> p (a, c) (b, c)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Yoneda p a b -> p a b
    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' = p (c, a) (c, b) -> Yoneda p (c, a) (c, b)
    p :-> Yoneda p
    forall (p :: * -> * -> *). Profunctor p => p :-> Yoneda p
    forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
    (ProfunctorMonad t, Profunctor p) =>
    p :-> t p
    proreturn (p (c, a) (c, b) -> Yoneda p (c, a) (c, b))
    -> (Yoneda p a b -> p (c, a) (c, b))
    -> Yoneda p a b
    -> Yoneda p (c, a) (c, b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . p a b -> p (c, a) (c, b)
    forall a b c. p a b -> p (c, a) (c, b)
    forall (p :: * -> * -> *) a b c.
    Strong p =>
    p a b -> p (c, a) (c, b)
    second' (p a b -> p (c, a) (c, b))
    -> (Yoneda p a b -> p a b) -> Yoneda p a b -> p (c, a) (c, b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Yoneda p a b -> p a b
    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' = p (Either a c) (Either b c) -> Yoneda p (Either a c) (Either b c)
    p :-> Yoneda p
    forall (p :: * -> * -> *). Profunctor p => p :-> Yoneda p
    forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
    (ProfunctorMonad t, Profunctor p) =>
    p :-> t p
    proreturn (p (Either a c) (Either b c) -> Yoneda p (Either a c) (Either b c))
    -> (Yoneda p a b -> p (Either a c) (Either b c))
    -> Yoneda p a b
    -> Yoneda p (Either a c) (Either b c)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . p a b -> p (Either a c) (Either b c)
    forall a b c. p a b -> p (Either a c) (Either b c)
    forall (p :: * -> * -> *) a b c.
    Choice p =>
    p a b -> p (Either a c) (Either b c)
    left' (p a b -> p (Either a c) (Either b c))
    -> (Yoneda p a b -> p a b)
    -> Yoneda p a b
    -> p (Either a c) (Either b c)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Yoneda p a b -> p a b
    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' = p (Either c a) (Either c b) -> Yoneda p (Either c a) (Either c b)
    p :-> Yoneda p
    forall (p :: * -> * -> *). Profunctor p => p :-> Yoneda p
    forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
    (ProfunctorMonad t, Profunctor p) =>
    p :-> t p
    proreturn (p (Either c a) (Either c b) -> Yoneda p (Either c a) (Either c b))
    -> (Yoneda p a b -> p (Either c a) (Either c b))
    -> Yoneda p a b
    -> Yoneda p (Either c a) (Either c b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . p a b -> p (Either c a) (Either c b)
    forall a b c. p a b -> p (Either c a) (Either c b)
    forall (p :: * -> * -> *) a b c.
    Choice p =>
    p a b -> p (Either c a) (Either c b)
    right' (p a b -> p (Either c a) (Either c b))
    -> (Yoneda p a b -> p a b)
    -> Yoneda p a b
    -> p (Either c a) (Either c b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Yoneda p a b -> p a b
    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 = p a b -> Yoneda p a b
    p :-> Yoneda p
    forall (p :: * -> * -> *). Profunctor p => p :-> Yoneda p
    forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
    (ProfunctorMonad t, Profunctor p) =>
    p :-> t p
    proreturn (p a b -> Yoneda p a b)
    -> (Yoneda p (a, d) (b, d) -> p a b)
    -> Yoneda p (a, d) (b, d)
    -> Yoneda p a b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . p (a, d) (b, d) -> p a b
    forall a d b. p (a, d) (b, d) -> p a b
    forall (p :: * -> * -> *) a d b.
    Costrong p =>
    p (a, d) (b, d) -> p a b
    unfirst (p (a, d) (b, d) -> p a b)
    -> (Yoneda p (a, d) (b, d) -> p (a, d) (b, d))
    -> Yoneda p (a, d) (b, d)
    -> p a b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Yoneda p (a, d) (b, d) -> p (a, d) (b, d)
    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 = p a b -> Yoneda p a b
    p :-> Yoneda p
    forall (p :: * -> * -> *). Profunctor p => p :-> Yoneda p
    forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
    (ProfunctorMonad t, Profunctor p) =>
    p :-> t p
    proreturn (p a b -> Yoneda p a b)
    -> (Yoneda p (d, a) (d, b) -> p a b)
    -> Yoneda p (d, a) (d, b)
    -> Yoneda p a b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . p (d, a) (d, b) -> p a b
    forall d a b. p (d, a) (d, b) -> p a b
    forall (p :: * -> * -> *) d a b.
    Costrong p =>
    p (d, a) (d, b) -> p a b
    unsecond (p (d, a) (d, b) -> p a b)
    -> (Yoneda p (d, a) (d, b) -> p (d, a) (d, b))
    -> Yoneda p (d, a) (d, b)
    -> p a b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Yoneda p (d, a) (d, b) -> p (d, a) (d, b)
    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 = p a b -> Yoneda p a b
    p :-> Yoneda p
    forall (p :: * -> * -> *). Profunctor p => p :-> Yoneda p
    forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
    (ProfunctorMonad t, Profunctor p) =>
    p :-> t p
    proreturn (p a b -> Yoneda p a b)
    -> (Yoneda p (Either a d) (Either b d) -> p a b)
    -> Yoneda p (Either a d) (Either b d)
    -> Yoneda p a b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . p (Either a d) (Either b d) -> p a b
    forall a d b. p (Either a d) (Either b d) -> p a b
    forall (p :: * -> * -> *) a d b.
    Cochoice p =>
    p (Either a d) (Either b d) -> p a b
    unleft (p (Either a d) (Either b d) -> p a b)
    -> (Yoneda p (Either a d) (Either b d)
        -> p (Either a d) (Either b d))
    -> Yoneda p (Either a d) (Either b d)
    -> p a b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Yoneda p (Either a d) (Either b d) -> p (Either a d) (Either b d)
    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 = p a b -> Yoneda p a b
    p :-> Yoneda p
    forall (p :: * -> * -> *). Profunctor p => p :-> Yoneda p
    forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
    (ProfunctorMonad t, Profunctor p) =>
    p :-> t p
    proreturn (p a b -> Yoneda p a b)
    -> (Yoneda p (Either d a) (Either d b) -> p a b)
    -> Yoneda p (Either d a) (Either d b)
    -> Yoneda p a b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . p (Either d a) (Either d b) -> p a b
    forall d a b. p (Either d a) (Either d b) -> p a b
    forall (p :: * -> * -> *) d a b.
    Cochoice p =>
    p (Either d a) (Either d b) -> p a b
    unright (p (Either d a) (Either d b) -> p a b)
    -> (Yoneda p (Either d a) (Either d b)
        -> p (Either d a) (Either d b))
    -> Yoneda p (Either d a) (Either d b)
    -> p a b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Yoneda p (Either d a) (Either d b) -> p (Either d a) (Either d b)
    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 = p (x -> a) (x -> b) -> Yoneda p (x -> a) (x -> b)
    p :-> Yoneda p
    forall (p :: * -> * -> *). Profunctor p => p :-> Yoneda p
    forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
    (ProfunctorMonad t, Profunctor p) =>
    p :-> t p
    proreturn (p (x -> a) (x -> b) -> Yoneda p (x -> a) (x -> b))
    -> (Yoneda p a b -> p (x -> a) (x -> b))
    -> Yoneda p a b
    -> Yoneda p (x -> a) (x -> b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . p a b -> p (x -> a) (x -> b)
    forall a b x. p a b -> p (x -> a) (x -> b)
    forall (p :: * -> * -> *) a b x.
    Closed p =>
    p a b -> p (x -> a) (x -> b)
    closed (p a b -> p (x -> a) (x -> b))
    -> (Yoneda p a b -> p a b) -> Yoneda p a b -> p (x -> a) (x -> b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Yoneda p a b -> p a b
    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' = p (f a) (f b) -> Yoneda p (f a) (f b)
    p :-> Yoneda p
    forall (p :: * -> * -> *). Profunctor p => p :-> Yoneda p
    forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
    (ProfunctorMonad t, Profunctor p) =>
    p :-> t p
    proreturn (p (f a) (f b) -> Yoneda p (f a) (f b))
    -> (Yoneda p a b -> p (f a) (f b))
    -> Yoneda p a b
    -> Yoneda p (f a) (f b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . p a b -> p (f a) (f b)
    forall (f :: * -> *) a b. Functor f => p a b -> p (f a) (f b)
    forall (p :: * -> * -> *) (f :: * -> *) a b.
    (Mapping p, Functor f) =>
    p a b -> p (f a) (f b)
    map' (p a b -> p (f a) (f b))
    -> (Yoneda p a b -> p a b) -> Yoneda p a b -> p (f a) (f b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Yoneda p a b -> p a b
    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' = p (f a) (f b) -> Yoneda p (f a) (f b)
    p :-> Yoneda p
    forall (p :: * -> * -> *). Profunctor p => p :-> Yoneda p
    forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
    (ProfunctorMonad t, Profunctor p) =>
    p :-> t p
    proreturn (p (f a) (f b) -> Yoneda p (f a) (f b))
    -> (Yoneda p a b -> p (f a) (f b))
    -> Yoneda p a b
    -> Yoneda p (f a) (f b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . p a b -> p (f a) (f b)
    forall (f :: * -> *) a b. Traversable f => p a b -> p (f a) (f b)
    forall (p :: * -> * -> *) (f :: * -> *) a b.
    (Traversing p, Traversable f) =>
    p a b -> p (f a) (f b)
    traverse' (p a b -> p (f a) (f b))
    -> (Yoneda p a b -> p a b) -> Yoneda p a b -> p (f a) (f b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Yoneda p a b -> p a b
    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 = p s t -> Yoneda p s t
    p :-> Yoneda p
    forall (p :: * -> * -> *). Profunctor p => p :-> Yoneda p
    forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
    (ProfunctorMonad t, Profunctor p) =>
    p :-> t p
    proreturn (p s t -> Yoneda p s t)
    -> (Yoneda p a b -> p s t) -> Yoneda p a b -> Yoneda p s t
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . (forall (f :: * -> *). Applicative f => (a -> f b) -> s -> f t)
    -> p a b -> p s t
    forall a b s t.
    (forall (f :: * -> *). Applicative f => (a -> f b) -> s -> f t)
    -> p a b -> p s t
    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 (a -> f b) -> s -> f t
    forall (f :: * -> *). Applicative f => (a -> f b) -> s -> f t
    f (p a b -> p s t)
    -> (Yoneda p a b -> p a b) -> Yoneda p a b -> p s t
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Yoneda p a b -> p a b
    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 = (a -> a) -> (b -> b) -> p a b -> Coyoneda p a b
    forall a x y b (p :: * -> * -> *).
    (a -> x) -> (y -> b) -> p x y -> Coyoneda p a b
    Coyoneda a -> a
    forall a. a -> a
    forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
    id b -> b
    forall a. a -> a
    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) = (a -> x) -> (y -> b) -> Coyoneda p x y -> Coyoneda p a b
    forall a b c d.
    (a -> b) -> (c -> d) -> Coyoneda p b c -> Coyoneda p a d
    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) = (a -> x) -> (y -> b) -> p x y -> Coyoneda p a b
    forall a x y b (p :: * -> * -> *).
    (a -> x) -> (y -> b) -> p x y -> Coyoneda p a b
    Coyoneda a -> x
    l (a -> b
    f (a -> b) -> (y -> a) -> y -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    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) = (a -> x) -> (y -> d) -> p x y -> Coyoneda p a d
    forall a x y b (p :: * -> * -> *).
    (a -> x) -> (y -> b) -> p x y -> Coyoneda p a b
    Coyoneda (b -> x
    l' (b -> x) -> (a -> b) -> a -> x
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    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 (c -> d) -> (y -> c) -> y -> d
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    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) = (a -> x) -> (y -> c) -> p x y -> Coyoneda p a c
    forall a x y b (p :: * -> * -> *).
    (a -> x) -> (y -> b) -> p x y -> Coyoneda p a b
    Coyoneda (b -> x
    l' (b -> x) -> (a -> b) -> a -> x
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    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) = (a -> x) -> (y -> c) -> p x y -> Coyoneda p a c
    forall a x y b (p :: * -> * -> *).
    (a -> x) -> (y -> b) -> p x y -> Coyoneda p a b
    Coyoneda a -> x
    l (b -> c
    r (b -> c) -> (y -> b) -> y -> c
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    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
    _ = Coyoneda p b c -> Coyoneda p a c
    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
    _ = (b -> b) -> a -> b
    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) = (a -> x) -> (y -> b) -> q x y -> Coyoneda q a b
    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 x y -> q x y
    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) = (a -> x) -> (y -> b) -> p x y -> p a b
    forall a b c d. (a -> b) -> (c -> d) -> p b c -> p a d
    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 = (a -> a) -> (b -> b) -> Coyoneda p a b -> Coyoneda (Coyoneda p) a b
    forall a x y b (p :: * -> * -> *).
    (a -> x) -> (y -> b) -> p x y -> Coyoneda p a b
    Coyoneda a -> a
    forall a. a -> a
    forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
    id b -> b
    forall a. a -> a
    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 = p a b -> Coyoneda p a b
    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 = Coyoneda (Coyoneda p) a b -> Coyoneda p a b
    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 = (a -> a) -> (a -> a) -> p a a -> Coyoneda p a a
    forall a x y b (p :: * -> * -> *).
    (a -> x) -> (y -> b) -> p x y -> Coyoneda p a b
    Coyoneda a -> a
    forall a. a -> a
    forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
    id a -> a
    forall a. a -> a
    forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
    id p a a
    forall a. p a a
    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 = (a -> x) -> (y -> c) -> p x y -> Coyoneda p a c
    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 p x y -> p x x -> p x y
    forall b c a. p b c -> p a b -> p a c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . (y -> x) -> p x y -> p x x
    forall b c a. (b -> c) -> p a b -> p a c
    forall (p :: * -> * -> *) b c a.
    Profunctor p =>
    (b -> c) -> p a b -> p a c
    rmap (b -> x
    lp (b -> x) -> (y -> b) -> y -> x
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    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' = p (a, c) (b, c) -> Coyoneda p (a, c) (b, c)
    forall (p :: * -> * -> *) a b. p a b -> Coyoneda p a b
    returnCoyoneda (p (a, c) (b, c) -> Coyoneda p (a, c) (b, c))
    -> (Coyoneda p a b -> p (a, c) (b, c))
    -> Coyoneda p a b
    -> Coyoneda p (a, c) (b, c)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . p a b -> p (a, c) (b, c)
    forall a b c. p a b -> p (a, c) (b, c)
    forall (p :: * -> * -> *) a b c.
    Strong p =>
    p a b -> p (a, c) (b, c)
    first' (p a b -> p (a, c) (b, c))
    -> (Coyoneda p a b -> p a b) -> Coyoneda p a b -> p (a, c) (b, c)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Coyoneda p a b -> p a b
    Coyoneda p :-> p
    forall (p :: * -> * -> *). Profunctor p => Coyoneda p :-> p
    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' = p (c, a) (c, b) -> Coyoneda p (c, a) (c, b)
    forall (p :: * -> * -> *) a b. p a b -> Coyoneda p a b
    returnCoyoneda (p (c, a) (c, b) -> Coyoneda p (c, a) (c, b))
    -> (Coyoneda p a b -> p (c, a) (c, b))
    -> Coyoneda p a b
    -> Coyoneda p (c, a) (c, b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . p a b -> p (c, a) (c, b)
    forall a b c. p a b -> p (c, a) (c, b)
    forall (p :: * -> * -> *) a b c.
    Strong p =>
    p a b -> p (c, a) (c, b)
    second' (p a b -> p (c, a) (c, b))
    -> (Coyoneda p a b -> p a b) -> Coyoneda p a b -> p (c, a) (c, b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Coyoneda p a b -> p a b
    Coyoneda p :-> p
    forall (p :: * -> * -> *). Profunctor p => Coyoneda p :-> p
    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' = p (Either a c) (Either b c) -> Coyoneda p (Either a c) (Either b c)
    forall (p :: * -> * -> *) a b. p a b -> Coyoneda p a b
    returnCoyoneda (p (Either a c) (Either b c)
     -> Coyoneda p (Either a c) (Either b c))
    -> (Coyoneda p a b -> p (Either a c) (Either b c))
    -> Coyoneda p a b
    -> Coyoneda p (Either a c) (Either b c)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . p a b -> p (Either a c) (Either b c)
    forall a b c. p a b -> p (Either a c) (Either b c)
    forall (p :: * -> * -> *) a b c.
    Choice p =>
    p a b -> p (Either a c) (Either b c)
    left' (p a b -> p (Either a c) (Either b c))
    -> (Coyoneda p a b -> p a b)
    -> Coyoneda p a b
    -> p (Either a c) (Either b c)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Coyoneda p a b -> p a b
    Coyoneda p :-> p
    forall (p :: * -> * -> *). Profunctor p => Coyoneda p :-> p
    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' = p (Either c a) (Either c b) -> Coyoneda p (Either c a) (Either c b)
    forall (p :: * -> * -> *) a b. p a b -> Coyoneda p a b
    returnCoyoneda (p (Either c a) (Either c b)
     -> Coyoneda p (Either c a) (Either c b))
    -> (Coyoneda p a b -> p (Either c a) (Either c b))
    -> Coyoneda p a b
    -> Coyoneda p (Either c a) (Either c b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . p a b -> p (Either c a) (Either c b)
    forall a b c. p a b -> p (Either c a) (Either c b)
    forall (p :: * -> * -> *) a b c.
    Choice p =>
    p a b -> p (Either c a) (Either c b)
    right' (p a b -> p (Either c a) (Either c b))
    -> (Coyoneda p a b -> p a b)
    -> Coyoneda p a b
    -> p (Either c a) (Either c b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Coyoneda p a b -> p a b
    Coyoneda p :-> p
    forall (p :: * -> * -> *). Profunctor p => Coyoneda p :-> p
    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 = p a b -> Coyoneda p a b
    forall (p :: * -> * -> *) a b. p a b -> Coyoneda p a b
    returnCoyoneda (p a b -> Coyoneda p a b)
    -> (Coyoneda p (a, d) (b, d) -> p a b)
    -> Coyoneda p (a, d) (b, d)
    -> Coyoneda p a b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . p (a, d) (b, d) -> p a b
    forall a d b. p (a, d) (b, d) -> p a b
    forall (p :: * -> * -> *) a d b.
    Costrong p =>
    p (a, d) (b, d) -> p a b
    unfirst (p (a, d) (b, d) -> p a b)
    -> (Coyoneda p (a, d) (b, d) -> p (a, d) (b, d))
    -> Coyoneda p (a, d) (b, d)
    -> p a b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Coyoneda p (a, d) (b, d) -> p (a, d) (b, d)
    Coyoneda p :-> p
    forall (p :: * -> * -> *). Profunctor p => Coyoneda p :-> p
    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 = p a b -> Coyoneda p a b
    forall (p :: * -> * -> *) a b. p a b -> Coyoneda p a b
    returnCoyoneda (p a b -> Coyoneda p a b)
    -> (Coyoneda p (d, a) (d, b) -> p a b)
    -> Coyoneda p (d, a) (d, b)
    -> Coyoneda p a b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . p (d, a) (d, b) -> p a b
    forall d a b. p (d, a) (d, b) -> p a b
    forall (p :: * -> * -> *) d a b.
    Costrong p =>
    p (d, a) (d, b) -> p a b
    unsecond (p (d, a) (d, b) -> p a b)
    -> (Coyoneda p (d, a) (d, b) -> p (d, a) (d, b))
    -> Coyoneda p (d, a) (d, b)
    -> p a b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Coyoneda p (d, a) (d, b) -> p (d, a) (d, b)
    Coyoneda p :-> p
    forall (p :: * -> * -> *). Profunctor p => Coyoneda p :-> p
    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 = p a b -> Coyoneda p a b
    forall (p :: * -> * -> *) a b. p a b -> Coyoneda p a b
    returnCoyoneda (p a b -> Coyoneda p a b)
    -> (Coyoneda p (Either a d) (Either b d) -> p a b)
    -> Coyoneda p (Either a d) (Either b d)
    -> Coyoneda p a b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . p (Either a d) (Either b d) -> p a b
    forall a d b. p (Either a d) (Either b d) -> p a b
    forall (p :: * -> * -> *) a d b.
    Cochoice p =>
    p (Either a d) (Either b d) -> p a b
    unleft (p (Either a d) (Either b d) -> p a b)
    -> (Coyoneda p (Either a d) (Either b d)
        -> p (Either a d) (Either b d))
    -> Coyoneda p (Either a d) (Either b d)
    -> p a b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Coyoneda p (Either a d) (Either b d) -> p (Either a d) (Either b d)
    Coyoneda p :-> p
    forall (p :: * -> * -> *). Profunctor p => Coyoneda p :-> p
    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 = p a b -> Coyoneda p a b
    forall (p :: * -> * -> *) a b. p a b -> Coyoneda p a b
    returnCoyoneda (p a b -> Coyoneda p a b)
    -> (Coyoneda p (Either d a) (Either d b) -> p a b)
    -> Coyoneda p (Either d a) (Either d b)
    -> Coyoneda p a b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . p (Either d a) (Either d b) -> p a b
    forall d a b. p (Either d a) (Either d b) -> p a b
    forall (p :: * -> * -> *) d a b.
    Cochoice p =>
    p (Either d a) (Either d b) -> p a b
    unright (p (Either d a) (Either d b) -> p a b)
    -> (Coyoneda p (Either d a) (Either d b)
        -> p (Either d a) (Either d b))
    -> Coyoneda p (Either d a) (Either d b)
    -> p a b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Coyoneda p (Either d a) (Either d b) -> p (Either d a) (Either d b)
    Coyoneda p :-> p
    forall (p :: * -> * -> *). Profunctor p => Coyoneda p :-> p
    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 = p (x -> a) (x -> b) -> Coyoneda p (x -> a) (x -> b)
    forall (p :: * -> * -> *) a b. p a b -> Coyoneda p a b
    returnCoyoneda (p (x -> a) (x -> b) -> Coyoneda p (x -> a) (x -> b))
    -> (Coyoneda p a b -> p (x -> a) (x -> b))
    -> Coyoneda p a b
    -> Coyoneda p (x -> a) (x -> b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . p a b -> p (x -> a) (x -> b)
    forall a b x. p a b -> p (x -> a) (x -> b)
    forall (p :: * -> * -> *) a b x.
    Closed p =>
    p a b -> p (x -> a) (x -> b)
    closed (p a b -> p (x -> a) (x -> b))
    -> (Coyoneda p a b -> p a b)
    -> Coyoneda p a b
    -> p (x -> a) (x -> b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Coyoneda p a b -> p a b
    Coyoneda p :-> p
    forall (p :: * -> * -> *). Profunctor p => Coyoneda p :-> p
    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' = p (f a) (f b) -> Coyoneda p (f a) (f b)
    forall (p :: * -> * -> *) a b. p a b -> Coyoneda p a b
    returnCoyoneda (p (f a) (f b) -> Coyoneda p (f a) (f b))
    -> (Coyoneda p a b -> p (f a) (f b))
    -> Coyoneda p a b
    -> Coyoneda p (f a) (f b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . p a b -> p (f a) (f b)
    forall (f :: * -> *) a b. Functor f => p a b -> p (f a) (f b)
    forall (p :: * -> * -> *) (f :: * -> *) a b.
    (Mapping p, Functor f) =>
    p a b -> p (f a) (f b)
    map' (p a b -> p (f a) (f b))
    -> (Coyoneda p a b -> p a b) -> Coyoneda p a b -> p (f a) (f b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Coyoneda p a b -> p a b
    Coyoneda p :-> p
    forall (p :: * -> * -> *). Profunctor p => Coyoneda p :-> p
    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' = p (f a) (f b) -> Coyoneda p (f a) (f b)
    forall (p :: * -> * -> *) a b. p a b -> Coyoneda p a b
    returnCoyoneda (p (f a) (f b) -> Coyoneda p (f a) (f b))
    -> (Coyoneda p a b -> p (f a) (f b))
    -> Coyoneda p a b
    -> Coyoneda p (f a) (f b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . p a b -> p (f a) (f b)
    forall (f :: * -> *) a b. Traversable f => p a b -> p (f a) (f b)
    forall (p :: * -> * -> *) (f :: * -> *) a b.
    (Traversing p, Traversable f) =>
    p a b -> p (f a) (f b)
    traverse' (p a b -> p (f a) (f b))
    -> (Coyoneda p a b -> p a b) -> Coyoneda p a b -> p (f a) (f b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Coyoneda p a b -> p a b
    Coyoneda p :-> p
    forall (p :: * -> * -> *). Profunctor p => Coyoneda p :-> p
    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 = p s t -> Coyoneda p s t
    forall (p :: * -> * -> *) a b. p a b -> Coyoneda p a b
    returnCoyoneda (p s t -> Coyoneda p s t)
    -> (Coyoneda p a b -> p s t) -> Coyoneda p a b -> Coyoneda p s t
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . (forall (f :: * -> *). Applicative f => (a -> f b) -> s -> f t)
    -> p a b -> p s t
    forall a b s t.
    (forall (f :: * -> *). Applicative f => (a -> f b) -> s -> f t)
    -> p a b -> p s t
    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 (a -> f b) -> s -> f t
    forall (f :: * -> *). Applicative f => (a -> f b) -> s -> f t
    f (p a b -> p s t)
    -> (Coyoneda p a b -> p a b) -> Coyoneda p a b -> p s t
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Coyoneda p a b -> p a b
    Coyoneda p :-> p
    forall (p :: * -> * -> *). Profunctor p => Coyoneda p :-> p
    forall (t :: (* -> * -> *) -> * -> * -> *) (p :: * -> * -> *).
    (ProfunctorComonad t, Profunctor p) =>
    t p :-> p
    proextract
      {-# INLINE wander #-}