    {-# LANGUAGE CPP #-}
    {-# LANGUAGE Trustworthy #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    -----------------------------------------------------------------------------
    -- |
    -- Copyright   :  (C) 2011-2018 Edward Kmett
    -- License     :  BSD-style (see the file LICENSE)
    --
    -- Maintainer  :  Edward Kmett <ekmett@gmail.com>
    -- Stability   :  provisional
    -- Portability :  portable
    --
    -- For a good explanation of profunctors in Haskell see Dan Piponi's article:
    --
    -- <http://blog.sigfpe.com/2011/07/profunctors-in-haskell.html>
    --
    -- This module includes /unsafe/ composition operators that are useful in
    -- practice when it comes to generating optimal core in GHC.
    --
    -- If you import this module you are taking upon yourself the obligation
    -- that you will only call the operators with @#@ in their names with functions
    -- that are operationally identity such as @newtype@ constructors or the field
    -- accessor of a @newtype@.
    --
    -- If you are ever in doubt, use 'rmap' or 'lmap'.
    ----------------------------------------------------------------------------
    module Data.Profunctor.Unsafe
      (
      -- * Profunctors
        Profunctor(..)
      ) where

    import Control.Arrow
    import Control.Category
    import Control.Comonad (Cokleisli(..))
    import Control.Monad (liftM)
    import Data.Bifunctor.Biff (Biff(..))
    import Data.Bifunctor.Clown (Clown(..))
    import Data.Bifunctor.Joker (Joker(..))
    import Data.Bifunctor.Product (Product(..))
    import Data.Bifunctor.Sum (Sum(..))
    import Data.Bifunctor.Tannen (Tannen(..))
    import Data.Coerce (Coercible, coerce)
    #if __GLASGOW_HASKELL__ < 710
    import Data.Functor
    #endif
    import Data.Functor.Contravariant (Contravariant(..))
    import Data.Tagged
    import Prelude hiding (id,(.))

    infixr 9 #.
    infixl 8 .#

    ----------------------------------------------------------------------------
    -- Profunctors
    ----------------------------------------------------------------------------

    -- | Formally, the class 'Profunctor' represents a profunctor
    -- from @Hask@ -> @Hask@.
    --
    -- Intuitively it is a bifunctor where the first argument is contravariant
    -- and the second argument is covariant.
    --
    -- You can define a 'Profunctor' by either defining 'dimap' or by defining both
    -- 'lmap' and 'rmap'.
    --
    -- If you supply 'dimap', you should ensure that:
    --
    -- @'dimap' 'id' 'id' ≡ 'id'@
    --
    -- If you supply 'lmap' and 'rmap', ensure:
    --
    -- @
    -- 'lmap' 'id' ≡ 'id'
    -- 'rmap' 'id' ≡ 'id'
    -- @
    --
    -- If you supply both, you should also ensure:
    --
    -- @'dimap' f g ≡ 'lmap' f '.' 'rmap' g@
    --
    -- These ensure by parametricity:
    --
    -- @
    -- 'dimap' (f '.' g) (h '.' i) ≡ 'dimap' g h '.' 'dimap' f i
    -- 'lmap' (f '.' g) ≡ 'lmap' g '.' 'lmap' f
    -- 'rmap' (f '.' g) ≡ 'rmap' f '.' 'rmap' g
    -- @
    class Profunctor p where
      -- | Map over both arguments at the same time.
      --
      -- @'dimap' f g ≡ 'lmap' f '.' 'rmap' g@
      dimap :: (a -> b) -> (c -> d) -> p b c -> p a d
      dimap f :: a -> b
    f g :: c -> d
    g = (a -> b) -> p b d -> p a d
    forall (p :: * -> * -> *) a b c.
    Profunctor p =>
    (a -> b) -> p b c -> p a c
    lmap a -> b
    f (p b d -> p a d) -> (p b c -> p b d) -> p b c -> p a d
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . (c -> d) -> p b c -> p b d
    forall (p :: * -> * -> *) b c a.
    Profunctor p =>
    (b -> c) -> p a b -> p a c
    rmap c -> d
    g
      {-# INLINE dimap #-}

      -- | Map the first argument contravariantly.
      --
      -- @'lmap' f ≡ 'dimap' f 'id'@
      lmap :: (a -> b) -> p b c -> p a c
      lmap f :: a -> b
    f = (a -> b) -> (c -> c) -> p b c -> p a c
    forall (p :: * -> * -> *) a b c d.
    Profunctor p =>
    (a -> b) -> (c -> d) -> p b c -> p a d
    dimap a -> b
    f c -> c
    forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
    id
      {-# INLINE lmap #-}

      -- | Map the second argument covariantly.
      --
      -- @'rmap' ≡ 'dimap' 'id'@
      rmap :: (b -> c) -> p a b -> p a c
      rmap = (a -> a) -> (b -> c) -> p a b -> p a c
    forall (p :: * -> * -> *) a b c d.
    Profunctor p =>
    (a -> b) -> (c -> d) -> p b c -> p a d
    dimap a -> a
    forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
    id
      {-# INLINE rmap #-}

      -- | Strictly map the second argument argument
      -- covariantly with a function that is assumed
      -- operationally to be a cast, such as a newtype
      -- constructor.
      --
      -- /Note:/ This operation is explicitly /unsafe/
      -- since an implementation may choose to use
      -- 'unsafeCoerce' to implement this combinator
      -- and it has no way to validate that your function
      -- meets the requirements.
      --
      -- If you implement this combinator with
      -- 'unsafeCoerce', then you are taking upon yourself
      -- the obligation that you don't use GADT-like
      -- tricks to distinguish values.
      --
      -- If you import "Data.Profunctor.Unsafe" you are
      -- taking upon yourself the obligation that you
      -- will only call this with a first argument that is
      -- operationally identity.
      --
      -- The semantics of this function with respect to bottoms
      -- should match the default definition:
      --
      -- @('Profuctor.Unsafe.#.') ≡ \\_ -> \\p -> p \`seq\` 'rmap' 'coerce' p@
      (#.) :: forall a b c q. Coercible c b => q b c -> p a b -> p a c
      (#.) = \_ -> \p :: p a b
    p -> p a b
    p p a b -> p a c -> p a c
    forall a b. a -> b -> b
    `seq` (b -> c) -> p a b -> p a c
    forall (p :: * -> * -> *) b c a.
    Profunctor p =>
    (b -> c) -> p a b -> p a c
    rmap ((c -> c) -> b -> c
    forall a b. Coercible a b => a -> b
    coerce (c -> c
    forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
    id :: c -> c) :: b -> c) p a b
    p
      {-# INLINE (#.) #-}

      -- | Strictly map the first argument argument
      -- contravariantly with a function that is assumed
      -- operationally to be a cast, such as a newtype
      -- constructor.
      --
      -- /Note:/ This operation is explicitly /unsafe/
      -- since an implementation may choose to use
      -- 'unsafeCoerce' to implement this combinator
      -- and it has no way to validate that your function
      -- meets the requirements.
      --
      -- If you implement this combinator with
      -- 'unsafeCoerce', then you are taking upon yourself
      -- the obligation that you don't use GADT-like
      -- tricks to distinguish values.
      --
      -- If you import "Data.Profunctor.Unsafe" you are
      -- taking upon yourself the obligation that you
      -- will only call this with a second argument that is
      -- operationally identity.
      --
      -- @('.#') ≡ \\p -> p \`seq\` \\f -> 'lmap' 'coerce' p@
      (.#) :: forall a b c q. Coercible b a => p b c -> q a b -> p a c
      (.#) = \p :: p b c
    p -> p b c
    p p b c -> (q a b -> p a c) -> q a b -> p a c
    forall a b. a -> b -> b
    `seq` \_ -> (a -> b) -> p b c -> p a c
    forall (p :: * -> * -> *) a b c.
    Profunctor p =>
    (a -> b) -> p b c -> p a c
    lmap ((b -> b) -> a -> b
    forall a b. Coercible a b => a -> b
    coerce (b -> b
    forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
    id :: b -> b) :: a -> b) p b c
    p
      {-# INLINE (.#) #-}

      {-# MINIMAL dimap | (lmap, rmap) #-}

    instance Profunctor (->) where
      dimap :: (a -> b) -> (c -> d) -> (b -> c) -> a -> d
    dimap ab :: a -> b
    ab cd :: c -> d
    cd bc :: b -> c
    bc = c -> d
    cd (c -> d) -> (a -> c) -> a -> d
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . b -> c
    bc (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
    ab
      {-# INLINE dimap #-}
      lmap :: (a -> b) -> (b -> c) -> a -> c
    lmap = ((b -> c) -> (a -> b) -> a -> c) -> (a -> b) -> (b -> c) -> a -> c
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip (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
    (.)
      {-# INLINE lmap #-}
      rmap :: (b -> c) -> (a -> b) -> a -> c
    rmap = (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
    (.)
      {-# INLINE rmap #-}
      #. :: q b c -> (a -> b) -> a -> c
    (#.) _ = (b -> b) -> a -> b
    forall a b. Coercible a b => a -> b
    coerce (\x :: b
    x -> b
    x :: b) :: forall a b. Coercible b a => a -> b
      .# :: (b -> c) -> q a b -> a -> c
    (.#) pbc :: b -> c
    pbc _ = (b -> c) -> a -> c
    forall a b. Coercible a b => a -> b
    coerce b -> c
    pbc
      {-# INLINE (#.) #-}
      {-# INLINE (.#) #-}

    instance Profunctor Tagged where
      dimap :: (a -> b) -> (c -> d) -> Tagged b c -> Tagged a d
    dimap _ f :: c -> d
    f (Tagged s :: c
    s) = d -> Tagged a d
    forall k (s :: k) b. b -> Tagged s b
    Tagged (c -> d
    f c
    s)
      {-# INLINE dimap #-}
      lmap :: (a -> b) -> Tagged b c -> Tagged a c
    lmap _ = Tagged b c -> Tagged a c
    forall k1 k2 (s :: k1) b (t :: k2). Tagged s b -> Tagged t b
    retag
      {-# INLINE lmap #-}
      rmap :: (b -> c) -> Tagged a b -> Tagged a c
    rmap = (b -> c) -> Tagged a b -> Tagged a c
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap
      {-# INLINE rmap #-}
      #. :: q b c -> Tagged a b -> Tagged a c
    (#.) _ = (b -> b) -> a -> b
    forall a b. Coercible a b => a -> b
    coerce (\x :: b
    x -> b
    x :: b) :: forall a b. Coercible b a => a -> b
      {-# INLINE (#.) #-}
      Tagged s :: c
    s .# :: Tagged b c -> q a b -> Tagged a c
    .# _ = c -> Tagged a c
    forall k (s :: k) b. b -> Tagged s b
    Tagged c
    s
      {-# INLINE (.#) #-}

    instance Monad m => Profunctor (Kleisli m) where
      dimap :: (a -> b) -> (c -> d) -> Kleisli m b c -> Kleisli m a d
    dimap f :: a -> b
    f g :: c -> d
    g (Kleisli h :: b -> m c
    h) = (a -> m d) -> Kleisli m a d
    forall (m :: * -> *) a b. (a -> m b) -> Kleisli m a b
    Kleisli ((c -> d) -> m c -> m d
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM c -> d
    g (m c -> m d) -> (a -> m c) -> a -> m d
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . b -> m c
    h (b -> m c) -> (a -> b) -> a -> m 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 dimap #-}
      lmap :: (a -> b) -> Kleisli m b c -> Kleisli m a c
    lmap k :: a -> b
    k (Kleisli f :: b -> m c
    f) = (a -> m c) -> Kleisli m a c
    forall (m :: * -> *) a b. (a -> m b) -> Kleisli m a b
    Kleisli (b -> m c
    f (b -> m c) -> (a -> b) -> a -> m 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
    k)
      {-# INLINE lmap #-}
      rmap :: (b -> c) -> Kleisli m a b -> Kleisli m a c
    rmap k :: b -> c
    k (Kleisli f :: a -> m b
    f) = (a -> m c) -> Kleisli m a c
    forall (m :: * -> *) a b. (a -> m b) -> Kleisli m a b
    Kleisli ((b -> c) -> m b -> m c
    forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
    liftM b -> c
    k (m b -> m c) -> (a -> m b) -> a -> m c
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . a -> m b
    f)
      {-# INLINE rmap #-}
      -- We cannot safely overload (#.) because we didn't provide the 'Monad'.
      .# :: Kleisli m b c -> q a b -> Kleisli m a c
    (.#) pbc :: Kleisli m b c
    pbc _ = Kleisli m b c -> Kleisli m a c
    forall a b. Coercible a b => a -> b
    coerce Kleisli m b c
    pbc
      {-# INLINE (.#) #-}

    instance Functor w => Profunctor (Cokleisli w) where
      dimap :: (a -> b) -> (c -> d) -> Cokleisli w b c -> Cokleisli w a d
    dimap f :: a -> b
    f g :: c -> d
    g (Cokleisli h :: w b -> c
    h) = (w a -> d) -> Cokleisli w a d
    forall k (w :: k -> *) (a :: k) b. (w a -> b) -> Cokleisli w a b
    Cokleisli (c -> d
    g (c -> d) -> (w a -> c) -> w a -> d
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . w b -> c
    h (w b -> c) -> (w a -> w b) -> w 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) -> w a -> w b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f)
      {-# INLINE dimap #-}
      lmap :: (a -> b) -> Cokleisli w b c -> Cokleisli w a c
    lmap k :: a -> b
    k (Cokleisli f :: w b -> c
    f) = (w a -> c) -> Cokleisli w a c
    forall k (w :: k -> *) (a :: k) b. (w a -> b) -> Cokleisli w a b
    Cokleisli (w b -> c
    f (w b -> c) -> (w a -> w b) -> w 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) -> w a -> w b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    k)
      {-# INLINE lmap #-}
      rmap :: (b -> c) -> Cokleisli w a b -> Cokleisli w a c
    rmap k :: b -> c
    k (Cokleisli f :: w a -> b
    f) = (w a -> c) -> Cokleisli w a c
    forall k (w :: k -> *) (a :: k) b. (w a -> b) -> Cokleisli w a b
    Cokleisli (b -> c
    k (b -> c) -> (w a -> b) -> w a -> c
    forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . w a -> b
    f)
      {-# INLINE rmap #-}
      -- We cannot safely overload (.#) because we didn't provide the 'Functor'.
      #. :: q b c -> Cokleisli w a b -> Cokleisli w a c
    (#.) _ = (b -> b) -> a -> b
    forall a b. Coercible a b => a -> b
    coerce (\x :: b
    x -> b
    x :: b) :: forall a b. Coercible b a => a -> b
      {-# INLINE (#.) #-}

    instance Contravariant f => Profunctor (Clown f) where
      lmap :: (a -> b) -> Clown f b c -> Clown f a c
    lmap f :: a -> b
    f (Clown fa :: f b
    fa) = f a -> Clown f a c
    forall k k1 (f :: k -> *) (a :: k) (b :: k1). f a -> Clown f a b
    Clown ((a -> b) -> f b -> f a
    forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
    contramap a -> b
    f f b
    fa)
      {-# INLINE lmap #-}
      rmap :: (b -> c) -> Clown f a b -> Clown f a c
    rmap _ (Clown fa :: f a
    fa) = f a -> Clown f a c
    forall k k1 (f :: k -> *) (a :: k) (b :: k1). f a -> Clown f a b
    Clown f a
    fa
      {-# INLINE rmap #-}
      dimap :: (a -> b) -> (c -> d) -> Clown f b c -> Clown f a d
    dimap f :: a -> b
    f _ (Clown fa :: f b
    fa) = f a -> Clown f a d
    forall k k1 (f :: k -> *) (a :: k) (b :: k1). f a -> Clown f a b
    Clown ((a -> b) -> f b -> f a
    forall (f :: * -> *) a b. Contravariant f => (a -> b) -> f b -> f a
    contramap a -> b
    f f b
    fa)
      {-# INLINE dimap #-}

    instance Functor f => Profunctor (Joker f) where
      lmap :: (a -> b) -> Joker f b c -> Joker f a c
    lmap _ (Joker fb :: f c
    fb) = f c -> Joker f a c
    forall k k1 (g :: k -> *) (a :: k1) (b :: k). g b -> Joker g a b
    Joker f c
    fb
      {-# INLINE lmap #-}
      rmap :: (b -> c) -> Joker f a b -> Joker f a c
    rmap g :: b -> c
    g (Joker fb :: f b
    fb) = f c -> Joker f a c
    forall k k1 (g :: k -> *) (a :: k1) (b :: k). g b -> Joker g a b
    Joker ((b -> c) -> f b -> f c
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap b -> c
    g f b
    fb)
      {-# INLINE rmap #-}
      dimap :: (a -> b) -> (c -> d) -> Joker f b c -> Joker f a d
    dimap _ g :: c -> d
    g (Joker fb :: f c
    fb) = f d -> Joker f a d
    forall k k1 (g :: k -> *) (a :: k1) (b :: k). g b -> Joker g a b
    Joker ((c -> d) -> f c -> f d
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap c -> d
    g f c
    fb)
      {-# INLINE dimap #-}

    instance (Profunctor p, Functor f, Functor g) => Profunctor (Biff p f g) where
      lmap :: (a -> b) -> Biff p f g b c -> Biff p f g a c
    lmap f :: a -> b
    f (Biff p :: p (f b) (g c)
    p) = p (f a) (g c) -> Biff p f g a c
    forall k k1 k2 k3 (p :: k -> k1 -> *) (f :: k2 -> k)
           (g :: k3 -> k1) (a :: k2) (b :: k3).
    p (f a) (g b) -> Biff p f g a b
    Biff ((f a -> f b) -> p (f b) (g c) -> p (f a) (g c)
    forall (p :: * -> * -> *) a b c.
    Profunctor p =>
    (a -> b) -> p b c -> p a c
    lmap ((a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f) p (f b) (g c)
    p)
      rmap :: (b -> c) -> Biff p f g a b -> Biff p f g a c
    rmap g :: b -> c
    g (Biff p :: p (f a) (g b)
    p) = p (f a) (g c) -> Biff p f g a c
    forall k k1 k2 k3 (p :: k -> k1 -> *) (f :: k2 -> k)
           (g :: k3 -> k1) (a :: k2) (b :: k3).
    p (f a) (g b) -> Biff p f g a b
    Biff ((g b -> g c) -> p (f a) (g b) -> p (f a) (g c)
    forall (p :: * -> * -> *) b c a.
    Profunctor p =>
    (b -> c) -> p a b -> p a c
    rmap ((b -> c) -> g b -> g c
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap b -> c
    g) p (f a) (g b)
    p)
      dimap :: (a -> b) -> (c -> d) -> Biff p f g b c -> Biff p f g a d
    dimap f :: a -> b
    f g :: c -> d
    g (Biff p :: p (f b) (g c)
    p) = p (f a) (g d) -> Biff p f g a d
    forall k k1 k2 k3 (p :: k -> k1 -> *) (f :: k2 -> k)
           (g :: k3 -> k1) (a :: k2) (b :: k3).
    p (f a) (g b) -> Biff p f g a b
    Biff ((f a -> f b) -> (g c -> g d) -> p (f b) (g c) -> p (f a) (g d)
    forall (p :: * -> * -> *) a b c d.
    Profunctor p =>
    (a -> b) -> (c -> d) -> p b c -> p a d
    dimap ((a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f) ((c -> d) -> g c -> g d
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap c -> d
    g) p (f b) (g c)
    p)

    instance (Profunctor p, Profunctor q) => Profunctor (Product p q) where
      lmap :: (a -> b) -> Product p q b c -> Product p q a c
    lmap  f :: a -> b
    f   (Pair p :: p b c
    p q :: q b c
    q) = p a c -> q a c -> Product p q a c
    forall k k1 (f :: k -> k1 -> *) (g :: k -> k1 -> *) (a :: k)
           (b :: k1).
    f a b -> g a b -> Product f g a b
    Pair ((a -> b) -> p b c -> p a c
    forall (p :: * -> * -> *) a b c.
    Profunctor p =>
    (a -> b) -> p b c -> p a c
    lmap a -> b
    f p b c
    p) ((a -> b) -> q b c -> q a c
    forall (p :: * -> * -> *) a b c.
    Profunctor p =>
    (a -> b) -> p b c -> p a c
    lmap a -> b
    f q b c
    q)
      {-# INLINE lmap #-}
      rmap :: (b -> c) -> Product p q a b -> Product p q a c
    rmap    g :: b -> c
    g (Pair p :: p a b
    p q :: q a b
    q) = p a c -> q a c -> Product p q a c
    forall k k1 (f :: k -> k1 -> *) (g :: k -> k1 -> *) (a :: k)
           (b :: k1).
    f a b -> g a b -> Product f g a b
    Pair ((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 -> c
    g p a b
    p) ((b -> c) -> q a b -> q a c
    forall (p :: * -> * -> *) b c a.
    Profunctor p =>
    (b -> c) -> p a b -> p a c
    rmap b -> c
    g q a b
    q)
      {-# INLINE rmap #-}
      dimap :: (a -> b) -> (c -> d) -> Product p q b c -> Product p q a d
    dimap f :: a -> b
    f g :: c -> d
    g (Pair p :: p b c
    p q :: q b c
    q) = p a d -> q a d -> Product p q a d
    forall k k1 (f :: k -> k1 -> *) (g :: k -> k1 -> *) (a :: k)
           (b :: k1).
    f a b -> g a b -> Product f g a b
    Pair ((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 -> b
    f c -> d
    g p b c
    p) ((a -> b) -> (c -> d) -> q b c -> q a d
    forall (p :: * -> * -> *) a b c d.
    Profunctor p =>
    (a -> b) -> (c -> d) -> p b c -> p a d
    dimap a -> b
    f c -> d
    g q b c
    q)
      {-# INLINE dimap #-}
      #. :: q b c -> Product p q a b -> Product p q a c
    (#.) f :: q b c
    f (Pair p :: p a b
    p q :: q a b
    q) = p a c -> q a c -> Product p q a c
    forall k k1 (f :: k -> k1 -> *) (g :: k -> k1 -> *) (a :: k)
           (b :: k1).
    f a b -> g a b -> Product f g a b
    Pair (q b c
    f q b c -> p a b -> p a c
    forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
    (Profunctor p, Coercible c b) =>
    q b c -> p a b -> p a c
    #. p a b
    p) (q b c
    f q b c -> q a b -> q a c
    forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
    (Profunctor p, Coercible c b) =>
    q b c -> p a b -> p a c
    #. q a b
    q)
      {-# INLINE (#.) #-}
      .# :: Product p q b c -> q a b -> Product p q a c
    (.#) (Pair p :: p b c
    p q :: q b c
    q) f :: q a b
    f = p a c -> q a c -> Product p q a c
    forall k k1 (f :: k -> k1 -> *) (g :: k -> k1 -> *) (a :: k)
           (b :: k1).
    f a b -> g a b -> Product f g a b
    Pair (p b c
    p p b c -> q a b -> p a c
    forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
    (Profunctor p, Coercible b a) =>
    p b c -> q a b -> p a c
    .# q a b
    f) (q b c
    q q b c -> q a b -> q a c
    forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
    (Profunctor p, Coercible b a) =>
    p b c -> q a b -> p a c
    .# q a b
    f)
      {-# INLINE (.#) #-}

    instance (Profunctor p, Profunctor q) => Profunctor (Sum p q) where
      lmap :: (a -> b) -> Sum p q b c -> Sum p q a c
    lmap f :: a -> b
    f (L2 x :: p b c
    x) = p a c -> Sum p q a c
    forall k k1 (p :: k -> k1 -> *) (q :: k -> k1 -> *) (a :: k)
           (b :: k1).
    p a b -> Sum p q a b
    L2 ((a -> b) -> p b c -> p a c
    forall (p :: * -> * -> *) a b c.
    Profunctor p =>
    (a -> b) -> p b c -> p a c
    lmap a -> b
    f p b c
    x)
      lmap f :: a -> b
    f (R2 y :: q b c
    y) = q a c -> Sum p q a c
    forall k k1 (p :: k -> k1 -> *) (q :: k -> k1 -> *) (a :: k)
           (b :: k1).
    q a b -> Sum p q a b
    R2 ((a -> b) -> q b c -> q a c
    forall (p :: * -> * -> *) a b c.
    Profunctor p =>
    (a -> b) -> p b c -> p a c
    lmap a -> b
    f q b c
    y)
      {-# INLINE lmap #-}
      rmap :: (b -> c) -> Sum p q a b -> Sum p q a c
    rmap g :: b -> c
    g (L2 x :: p a b
    x) = p a c -> Sum p q a c
    forall k k1 (p :: k -> k1 -> *) (q :: k -> k1 -> *) (a :: k)
           (b :: k1).
    p a b -> Sum p q a b
    L2 ((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 -> c
    g p a b
    x)
      rmap g :: b -> c
    g (R2 y :: q a b
    y) = q a c -> Sum p q a c
    forall k k1 (p :: k -> k1 -> *) (q :: k -> k1 -> *) (a :: k)
           (b :: k1).
    q a b -> Sum p q a b
    R2 ((b -> c) -> q a b -> q a c
    forall (p :: * -> * -> *) b c a.
    Profunctor p =>
    (b -> c) -> p a b -> p a c
    rmap b -> c
    g q a b
    y)
      {-# INLINE rmap #-}
      dimap :: (a -> b) -> (c -> d) -> Sum p q b c -> Sum p q a d
    dimap f :: a -> b
    f g :: c -> d
    g (L2 x :: p b c
    x) = p a d -> Sum p q a d
    forall k k1 (p :: k -> k1 -> *) (q :: k -> k1 -> *) (a :: k)
           (b :: k1).
    p a b -> Sum p q a b
    L2 ((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 -> b
    f c -> d
    g p b c
    x)
      dimap f :: a -> b
    f g :: c -> d
    g (R2 y :: q b c
    y) = q a d -> Sum p q a d
    forall k k1 (p :: k -> k1 -> *) (q :: k -> k1 -> *) (a :: k)
           (b :: k1).
    q a b -> Sum p q a b
    R2 ((a -> b) -> (c -> d) -> q b c -> q a d
    forall (p :: * -> * -> *) a b c d.
    Profunctor p =>
    (a -> b) -> (c -> d) -> p b c -> p a d
    dimap a -> b
    f c -> d
    g q b c
    y)
      {-# INLINE dimap #-}
      f :: q b c
    f #. :: q b c -> Sum p q a b -> Sum p q a c
    #. L2 x :: p a b
    x = p a c -> Sum p q a c
    forall k k1 (p :: k -> k1 -> *) (q :: k -> k1 -> *) (a :: k)
           (b :: k1).
    p a b -> Sum p q a b
    L2 (q b c
    f q b c -> p a b -> p a c
    forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
    (Profunctor p, Coercible c b) =>
    q b c -> p a b -> p a c
    #. p a b
    x)
      f :: q b c
    f #. R2 y :: q a b
    y = q a c -> Sum p q a c
    forall k k1 (p :: k -> k1 -> *) (q :: k -> k1 -> *) (a :: k)
           (b :: k1).
    q a b -> Sum p q a b
    R2 (q b c
    f q b c -> q a b -> q a c
    forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
    (Profunctor p, Coercible c b) =>
    q b c -> p a b -> p a c
    #. q a b
    y)
      {-# INLINE (#.) #-}
      L2 x :: p b c
    x .# :: Sum p q b c -> q a b -> Sum p q a c
    .# f :: q a b
    f = p a c -> Sum p q a c
    forall k k1 (p :: k -> k1 -> *) (q :: k -> k1 -> *) (a :: k)
           (b :: k1).
    p a b -> Sum p q a b
    L2 (p b c
    x p b c -> q a b -> p a c
    forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
    (Profunctor p, Coercible b a) =>
    p b c -> q a b -> p a c
    .# q a b
    f)
      R2 y :: q b c
    y .# f :: q a b
    f = q a c -> Sum p q a c
    forall k k1 (p :: k -> k1 -> *) (q :: k -> k1 -> *) (a :: k)
           (b :: k1).
    q a b -> Sum p q a b
    R2 (q b c
    y q b c -> q a b -> q a c
    forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
    (Profunctor p, Coercible b a) =>
    p b c -> q a b -> p a c
    .# q a b
    f)
      {-# INLINE (.#) #-}

    instance (Functor f, Profunctor p) => Profunctor (Tannen f p) where
      lmap :: (a -> b) -> Tannen f p b c -> Tannen f p a c
    lmap f :: a -> b
    f (Tannen h :: f (p b c)
    h) = f (p a c) -> Tannen f p a c
    forall k k1 k2 (f :: k -> *) (p :: k1 -> k2 -> k) (a :: k1)
           (b :: k2).
    f (p a b) -> Tannen f p a b
    Tannen ((a -> b) -> p b c -> p a c
    forall (p :: * -> * -> *) a b c.
    Profunctor p =>
    (a -> b) -> p b c -> p a c
    lmap a -> b
    f (p b c -> p a c) -> f (p b c) -> f (p a c)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> f (p b c)
    h)
      {-# INLINE lmap #-}
      rmap :: (b -> c) -> Tannen f p a b -> Tannen f p a c
    rmap g :: b -> c
    g (Tannen h :: f (p a b)
    h) = f (p a c) -> Tannen f p a c
    forall k k1 k2 (f :: k -> *) (p :: k1 -> k2 -> k) (a :: k1)
           (b :: k2).
    f (p a b) -> Tannen f p a b
    Tannen ((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 -> c
    g (p a b -> p a c) -> f (p a b) -> f (p a c)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> f (p a b)
    h)
      {-# INLINE rmap #-}
      dimap :: (a -> b) -> (c -> d) -> Tannen f p b c -> Tannen f p a d
    dimap f :: a -> b
    f g :: c -> d
    g (Tannen h :: f (p b c)
    h) = f (p a d) -> Tannen f p a d
    forall k k1 k2 (f :: k -> *) (p :: k1 -> k2 -> k) (a :: k1)
           (b :: k2).
    f (p a b) -> Tannen f p a b
    Tannen ((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 -> b
    f c -> d
    g (p b c -> p a d) -> f (p b c) -> f (p a d)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> f (p b c)
    h)
      {-# INLINE dimap #-}
      #. :: q b c -> Tannen f p a b -> Tannen f p a c
    (#.) f :: q b c
    f (Tannen h :: f (p a b)
    h) = f (p a c) -> Tannen f p a c
    forall k k1 k2 (f :: k -> *) (p :: k1 -> k2 -> k) (a :: k1)
           (b :: k2).
    f (p a b) -> Tannen f p a b
    Tannen ((q b c
    f q b c -> p a b -> p a c
    forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
    (Profunctor p, Coercible c b) =>
    q b c -> p a b -> p a c
    #.) (p a b -> p a c) -> f (p a b) -> f (p a c)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> f (p a b)
    h)
      {-# INLINE (#.) #-}
      .# :: Tannen f p b c -> q a b -> Tannen f p a c
    (.#) (Tannen h :: f (p b c)
    h) f :: q a b
    f = f (p a c) -> Tannen f p a c
    forall k k1 k2 (f :: k -> *) (p :: k1 -> k2 -> k) (a :: k1)
           (b :: k2).
    f (p a b) -> Tannen f p a b
    Tannen ((p b c -> q a b -> p a c
    forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
    (Profunctor p, Coercible b a) =>
    p b c -> q a b -> p a c
    .# q a b
    f) (p b c -> p a c) -> f (p b c) -> f (p a c)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> f (p b c)
    h)
      {-# INLINE (.#) #-}