-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Profunctors
--   
--   Profunctors
@package profunctors
@version 5.2


-- | For a good explanation of profunctors in Haskell see Dan Piponi's
--   article:
--   
--   <a>http://blog.sigfpe.com/2011/07/profunctors-in-haskell.html</a>
--   
--   This module includes <i>unsafe</i> 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 <tt>#</tt> in their names
--   with functions that are operationally identity such as
--   <tt>newtype</tt> constructors or the field accessor of a
--   <tt>newtype</tt>.
--   
--   If you are ever in doubt, use <a>rmap</a> or <a>lmap</a>.
module Data.Profunctor.Unsafe

-- | Formally, the class <a>Profunctor</a> represents a profunctor from
--   <tt>Hask</tt> -&gt; <tt>Hask</tt>.
--   
--   Intuitively it is a bifunctor where the first argument is
--   contravariant and the second argument is covariant.
--   
--   You can define a <a>Profunctor</a> by either defining <a>dimap</a> or
--   by defining both <a>lmap</a> and <a>rmap</a>.
--   
--   If you supply <a>dimap</a>, you should ensure that:
--   
--   <pre>
--   <a>dimap</a> <a>id</a> <a>id</a> ≡ <a>id</a>
--   </pre>
--   
--   If you supply <a>lmap</a> and <a>rmap</a>, ensure:
--   
--   <pre>
--   <a>lmap</a> <a>id</a> ≡ <a>id</a>
--   <a>rmap</a> <a>id</a> ≡ <a>id</a>
--   </pre>
--   
--   If you supply both, you should also ensure:
--   
--   <pre>
--   <a>dimap</a> f g ≡ <a>lmap</a> f <a>.</a> <a>rmap</a> g
--   </pre>
--   
--   These ensure by parametricity:
--   
--   <pre>
--   <a>dimap</a> (f <a>.</a> g) (h <a>.</a> i) ≡ <a>dimap</a> g h <a>.</a> <a>dimap</a> f i
--   <a>lmap</a> (f <a>.</a> g) ≡ <a>lmap</a> g <a>.</a> <a>lmap</a> f
--   <a>rmap</a> (f <a>.</a> g) ≡ <a>rmap</a> f <a>.</a> <a>rmap</a> g
--   </pre>
class Profunctor p where dimap f g = lmap f . rmap g lmap f = dimap f id rmap = dimap id (#.) = \ f -> \ p -> p `seq` rmap f p (.#) = \ p -> p `seq` \ f -> lmap f p

-- | Map over both arguments at the same time.
--   
--   <pre>
--   <a>dimap</a> f g ≡ <a>lmap</a> f <a>.</a> <a>rmap</a> g
--   </pre>
dimap :: Profunctor p => (a -> b) -> (c -> d) -> p b c -> p a d

-- | Map the first argument contravariantly.
--   
--   <pre>
--   <a>lmap</a> f ≡ <a>dimap</a> f <a>id</a>
--   </pre>
lmap :: Profunctor p => (a -> b) -> p b c -> p a c

-- | Map the second argument covariantly.
--   
--   <pre>
--   <a>rmap</a> ≡ <a>dimap</a> <a>id</a>
--   </pre>
rmap :: Profunctor p => (b -> c) -> p a b -> p a c

-- | Strictly map the second argument argument covariantly with a function
--   that is assumed operationally to be a cast, such as a newtype
--   constructor.
--   
--   <i>Note:</i> This operation is explicitly <i>unsafe</i> since an
--   implementation may choose to use <tt>unsafeCoerce</tt> to implement
--   this combinator and it has no way to validate that your function meets
--   the requirements.
--   
--   If you implement this combinator with <tt>unsafeCoerce</tt>, then you
--   are taking upon yourself the obligation that you don't use GADT-like
--   tricks to distinguish values.
--   
--   If you import <a>Data.Profunctor.Unsafe</a> 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:
--   
--   <pre>
--   (<a>#.</a>) ≡ \f -&gt; \p -&gt; p `seq` <a>rmap</a> f p
--   </pre>
(#.) :: (Profunctor p, Coercible c b) => (b -> c) -> p a b -> p a c

-- | Strictly map the first argument argument contravariantly with a
--   function that is assumed operationally to be a cast, such as a newtype
--   constructor.
--   
--   <i>Note:</i> This operation is explicitly <i>unsafe</i> since an
--   implementation may choose to use <tt>unsafeCoerce</tt> to implement
--   this combinator and it has no way to validate that your function meets
--   the requirements.
--   
--   If you implement this combinator with <tt>unsafeCoerce</tt>, then you
--   are taking upon yourself the obligation that you don't use GADT-like
--   tricks to distinguish values.
--   
--   If you import <a>Data.Profunctor.Unsafe</a> you are taking upon
--   yourself the obligation that you will only call this with a second
--   argument that is operationally identity.
--   
--   <pre>
--   (<a>.#</a>) ≡ \p -&gt; p `seq` \f -&gt; <a>lmap</a> f p
--   </pre>
(.#) :: (Profunctor p, Coercible b a) => p b c -> (a -> b) -> p a c
instance Data.Profunctor.Unsafe.Profunctor (->)
instance Data.Profunctor.Unsafe.Profunctor Data.Tagged.Tagged
instance GHC.Base.Monad m => Data.Profunctor.Unsafe.Profunctor (Control.Arrow.Kleisli m)
instance GHC.Base.Functor w => Data.Profunctor.Unsafe.Profunctor (Control.Comonad.Cokleisli w)
instance Data.Functor.Contravariant.Contravariant f => Data.Profunctor.Unsafe.Profunctor (Data.Bifunctor.Clown.Clown f)
instance GHC.Base.Functor f => Data.Profunctor.Unsafe.Profunctor (Data.Bifunctor.Joker.Joker f)
instance (Data.Profunctor.Unsafe.Profunctor p, GHC.Base.Functor f, GHC.Base.Functor g) => Data.Profunctor.Unsafe.Profunctor (Data.Bifunctor.Biff.Biff p f g)
instance (Data.Profunctor.Unsafe.Profunctor p, Data.Profunctor.Unsafe.Profunctor q) => Data.Profunctor.Unsafe.Profunctor (Data.Bifunctor.Product.Product p q)
instance (GHC.Base.Functor f, Data.Profunctor.Unsafe.Profunctor p) => Data.Profunctor.Unsafe.Profunctor (Data.Bifunctor.Tannen.Tannen f p)


-- | For a good explanation of profunctors in Haskell see Dan Piponi's
--   article:
--   
--   <a>http://blog.sigfpe.com/2011/07/profunctors-in-haskell.html</a>
--   
--   For more information on strength and costrength, see:
--   
--   <a>http://comonad.com/reader/2008/deriving-strength-from-laziness/</a>
module Data.Profunctor.Types

-- | Formally, the class <a>Profunctor</a> represents a profunctor from
--   <tt>Hask</tt> -&gt; <tt>Hask</tt>.
--   
--   Intuitively it is a bifunctor where the first argument is
--   contravariant and the second argument is covariant.
--   
--   You can define a <a>Profunctor</a> by either defining <a>dimap</a> or
--   by defining both <a>lmap</a> and <a>rmap</a>.
--   
--   If you supply <a>dimap</a>, you should ensure that:
--   
--   <pre>
--   <a>dimap</a> <a>id</a> <a>id</a> ≡ <a>id</a>
--   </pre>
--   
--   If you supply <a>lmap</a> and <a>rmap</a>, ensure:
--   
--   <pre>
--   <a>lmap</a> <a>id</a> ≡ <a>id</a>
--   <a>rmap</a> <a>id</a> ≡ <a>id</a>
--   </pre>
--   
--   If you supply both, you should also ensure:
--   
--   <pre>
--   <a>dimap</a> f g ≡ <a>lmap</a> f <a>.</a> <a>rmap</a> g
--   </pre>
--   
--   These ensure by parametricity:
--   
--   <pre>
--   <a>dimap</a> (f <a>.</a> g) (h <a>.</a> i) ≡ <a>dimap</a> g h <a>.</a> <a>dimap</a> f i
--   <a>lmap</a> (f <a>.</a> g) ≡ <a>lmap</a> g <a>.</a> <a>lmap</a> f
--   <a>rmap</a> (f <a>.</a> g) ≡ <a>rmap</a> f <a>.</a> <a>rmap</a> g
--   </pre>
class Profunctor p where dimap f g = lmap f . rmap g lmap f = dimap f id rmap = dimap id (#.) = \ f -> \ p -> p `seq` rmap f p (.#) = \ p -> p `seq` \ f -> lmap f p

-- | Map over both arguments at the same time.
--   
--   <pre>
--   <a>dimap</a> f g ≡ <a>lmap</a> f <a>.</a> <a>rmap</a> g
--   </pre>
dimap :: Profunctor p => (a -> b) -> (c -> d) -> p b c -> p a d

-- | Map the first argument contravariantly.
--   
--   <pre>
--   <a>lmap</a> f ≡ <a>dimap</a> f <a>id</a>
--   </pre>
lmap :: Profunctor p => (a -> b) -> p b c -> p a c

-- | Map the second argument covariantly.
--   
--   <pre>
--   <a>rmap</a> ≡ <a>dimap</a> <a>id</a>
--   </pre>
rmap :: Profunctor p => (b -> c) -> p a b -> p a c

-- | Lift a <a>Functor</a> into a <a>Profunctor</a> (forwards).
newtype Star f d c
Star :: (d -> f c) -> Star f d c
[runStar] :: Star f d c -> d -> f c

-- | Lift a <a>Functor</a> into a <a>Profunctor</a> (backwards).
newtype Costar f d c
Costar :: (f d -> c) -> Costar f d c
[runCostar] :: Costar f d c -> f d -> c

-- | Wrap an arrow for use as a <a>Profunctor</a>.
newtype WrappedArrow p a b
WrapArrow :: p a b -> WrappedArrow p a b
[unwrapArrow] :: WrappedArrow p a b -> p a b
newtype Forget r a b
Forget :: (a -> r) -> Forget r a b
[runForget] :: Forget r a b -> a -> r
type (:->) p q = forall a b. p a b -> q a b
instance GHC.Base.Functor f => Data.Profunctor.Unsafe.Profunctor (Data.Profunctor.Types.Star f)
instance GHC.Base.Functor f => GHC.Base.Functor (Data.Profunctor.Types.Star f a)
instance GHC.Base.Applicative f => GHC.Base.Applicative (Data.Profunctor.Types.Star f a)
instance GHC.Base.Alternative f => GHC.Base.Alternative (Data.Profunctor.Types.Star f a)
instance GHC.Base.Monad f => GHC.Base.Monad (Data.Profunctor.Types.Star f a)
instance GHC.Base.MonadPlus f => GHC.Base.MonadPlus (Data.Profunctor.Types.Star f a)
instance Data.Distributive.Distributive f => Data.Distributive.Distributive (Data.Profunctor.Types.Star f a)
instance GHC.Base.Functor f => Data.Profunctor.Unsafe.Profunctor (Data.Profunctor.Types.Costar f)
instance Data.Distributive.Distributive (Data.Profunctor.Types.Costar f d)
instance GHC.Base.Functor (Data.Profunctor.Types.Costar f a)
instance GHC.Base.Applicative (Data.Profunctor.Types.Costar f a)
instance GHC.Base.Monad (Data.Profunctor.Types.Costar f a)
instance Control.Category.Category p => Control.Category.Category (Data.Profunctor.Types.WrappedArrow p)
instance Control.Arrow.Arrow p => Control.Arrow.Arrow (Data.Profunctor.Types.WrappedArrow p)
instance Control.Arrow.ArrowZero p => Control.Arrow.ArrowZero (Data.Profunctor.Types.WrappedArrow p)
instance Control.Arrow.ArrowChoice p => Control.Arrow.ArrowChoice (Data.Profunctor.Types.WrappedArrow p)
instance Control.Arrow.ArrowApply p => Control.Arrow.ArrowApply (Data.Profunctor.Types.WrappedArrow p)
instance Control.Arrow.ArrowLoop p => Control.Arrow.ArrowLoop (Data.Profunctor.Types.WrappedArrow p)
instance Control.Arrow.Arrow p => Data.Profunctor.Unsafe.Profunctor (Data.Profunctor.Types.WrappedArrow p)
instance Data.Profunctor.Unsafe.Profunctor (Data.Profunctor.Types.Forget r)
instance GHC.Base.Functor (Data.Profunctor.Types.Forget r a)
instance Data.Foldable.Foldable (Data.Profunctor.Types.Forget r a)
instance Data.Traversable.Traversable (Data.Profunctor.Types.Forget r a)


module Data.Profunctor.Monad
class ProfunctorFunctor t
promap :: (ProfunctorFunctor t, Profunctor p) => (p :-> q) -> t p :-> t q
class ProfunctorFunctor t => ProfunctorMonad t
proreturn :: (ProfunctorMonad t, Profunctor p) => p :-> t p
projoin :: (ProfunctorMonad t, Profunctor p) => t (t p) :-> t p
class ProfunctorFunctor t => ProfunctorComonad t
proextract :: (ProfunctorComonad t, Profunctor p) => t p :-> p
produplicate :: (ProfunctorComonad t, Profunctor p) => t p :-> t (t p)
instance GHC.Base.Functor f => Data.Profunctor.Monad.ProfunctorFunctor (Data.Bifunctor.Tannen.Tannen f)
instance Data.Profunctor.Monad.ProfunctorFunctor (Data.Bifunctor.Product.Product p)
instance Data.Profunctor.Monad.ProfunctorFunctor (Data.Bifunctor.Sum.Sum p)
instance GHC.Base.Monad f => Data.Profunctor.Monad.ProfunctorMonad (Data.Bifunctor.Tannen.Tannen f)
instance Data.Profunctor.Monad.ProfunctorMonad (Data.Bifunctor.Sum.Sum p)
instance Control.Comonad.Comonad f => Data.Profunctor.Monad.ProfunctorComonad (Data.Bifunctor.Tannen.Tannen f)
instance Data.Profunctor.Monad.ProfunctorComonad (Data.Bifunctor.Product.Product p)


module Data.Profunctor.Adjunction
class (ProfunctorFunctor f, ProfunctorFunctor u) => ProfunctorAdjunction f u | f -> u, u -> f
unit :: (ProfunctorAdjunction f u, Profunctor p) => p :-> u (f p)
counit :: (ProfunctorAdjunction f u, Profunctor p) => f (u p) :-> p


module Data.Profunctor.Strong

-- | Generalizing <a>Star</a> of a strong <a>Functor</a>
--   
--   <i>Note:</i> Every <a>Functor</a> in Haskell is strong with respect to
--   <tt>(,)</tt>.
--   
--   This describes profunctor strength with respect to the product
--   structure of Hask.
--   
--   <a>http://www-kb.is.s.u-tokyo.ac.jp/~asada/papers/arrStrMnd.pdf</a>
class Profunctor p => Strong p where first' = dimap swap swap . second' second' = dimap swap swap . first'
first' :: Strong p => p a b -> p (a, c) (b, c)
second' :: Strong p => p a b -> p (c, a) (c, b)
uncurry' :: Strong p => p a (b -> c) -> p (a, b) c

-- | <a>Tambara</a> cofreely makes any <a>Profunctor</a> <a>Strong</a>.
newtype Tambara p a b
Tambara :: (forall c. p (a, c) (b, c)) -> Tambara p a b
[runTambara] :: Tambara p a b -> forall c. p (a, c) (b, c)

-- | <pre>
--   <a>tambara</a> <a>.</a> <a>untambara</a> ≡ <a>id</a>
--   <a>untambara</a> <a>.</a> <a>tambara</a> ≡ <a>id</a>
--   </pre>
tambara :: Strong p => (p :-> q) -> p :-> Tambara q

-- | <pre>
--   <a>tambara</a> <a>.</a> <a>untambara</a> ≡ <a>id</a>
--   <a>untambara</a> <a>.</a> <a>tambara</a> ≡ <a>id</a>
--   </pre>
untambara :: Profunctor q => (p :-> Tambara q) -> p :-> q

-- | Pastro -| Tambara
--   
--   <pre>
--   Pastro p ~ exists z. Costar ((,)z) <tt>Procompose</tt> p <tt>Procompose</tt> Star ((,)z)
--   </pre>
--   
--   <a>Pastro</a> freely makes any <a>Profunctor</a> <a>Strong</a>.
data Pastro p a b
[Pastro] :: ((y, z) -> b) -> p x y -> (a -> (x, z)) -> Pastro p a b

-- | Analogous to <a>ArrowLoop</a>, <a>loop</a> = <a>unfirst</a>
class Profunctor p => Costrong p where unfirst = unsecond . dimap swap swap unsecond = unfirst . dimap swap swap
unfirst :: Costrong p => p (a, d) (b, d) -> p a b
unsecond :: Costrong p => p (d, a) (d, b) -> p a b

-- | Cotambara cofreely constructs costrength
data Cotambara q a b
[Cotambara] :: Costrong r => (r :-> q) -> r a b -> Cotambara q a b

-- | <pre>
--   <a>cotambara</a> <a>.</a> <a>uncotambara</a> ≡ <a>id</a>
--   <a>uncotambara</a> <a>.</a> <a>cotambara</a> ≡ <a>id</a>
--   </pre>
cotambara :: Costrong p => (p :-> q) -> p :-> Cotambara q

-- | <pre>
--   <a>cotambara</a> <a>.</a> <a>uncotambara</a> ≡ <a>id</a>
--   <a>uncotambara</a> <a>.</a> <a>cotambara</a> ≡ <a>id</a>
--   </pre>
uncotambara :: Profunctor q => (p :-> Cotambara q) -> p :-> q

-- | Copastro -| Cotambara
--   
--   Copastro freely constructs costrength
newtype Copastro p a b
Copastro :: (forall r. Costrong r => (forall x y. p x y -> r x y) -> r a b) -> Copastro p a b
[runCopastro] :: Copastro p a b -> forall r. Costrong r => (forall x y. p x y -> r x y) -> r a b
instance Data.Profunctor.Strong.Strong (->)
instance GHC.Base.Monad m => Data.Profunctor.Strong.Strong (Control.Arrow.Kleisli m)
instance GHC.Base.Functor m => Data.Profunctor.Strong.Strong (Data.Profunctor.Types.Star m)
instance Control.Arrow.Arrow p => Data.Profunctor.Strong.Strong (Data.Profunctor.Types.WrappedArrow p)
instance Data.Profunctor.Strong.Strong (Data.Profunctor.Types.Forget r)
instance Data.Functor.Contravariant.Contravariant f => Data.Profunctor.Strong.Strong (Data.Bifunctor.Clown.Clown f)
instance (Data.Profunctor.Strong.Strong p, Data.Profunctor.Strong.Strong q) => Data.Profunctor.Strong.Strong (Data.Bifunctor.Product.Product p q)
instance (GHC.Base.Functor f, Data.Profunctor.Strong.Strong p) => Data.Profunctor.Strong.Strong (Data.Bifunctor.Tannen.Tannen f p)
instance Data.Profunctor.Unsafe.Profunctor p => Data.Profunctor.Unsafe.Profunctor (Data.Profunctor.Strong.Tambara p)
instance Data.Profunctor.Monad.ProfunctorFunctor Data.Profunctor.Strong.Tambara
instance Data.Profunctor.Monad.ProfunctorComonad Data.Profunctor.Strong.Tambara
instance Data.Profunctor.Unsafe.Profunctor p => Data.Profunctor.Strong.Strong (Data.Profunctor.Strong.Tambara p)
instance Control.Category.Category p => Control.Category.Category (Data.Profunctor.Strong.Tambara p)
instance Control.Arrow.Arrow p => Control.Arrow.Arrow (Data.Profunctor.Strong.Tambara p)
instance Control.Arrow.ArrowChoice p => Control.Arrow.ArrowChoice (Data.Profunctor.Strong.Tambara p)
instance Control.Arrow.ArrowApply p => Control.Arrow.ArrowApply (Data.Profunctor.Strong.Tambara p)
instance Control.Arrow.ArrowLoop p => Control.Arrow.ArrowLoop (Data.Profunctor.Strong.Tambara p)
instance Control.Arrow.ArrowZero p => Control.Arrow.ArrowZero (Data.Profunctor.Strong.Tambara p)
instance Control.Arrow.ArrowPlus p => Control.Arrow.ArrowPlus (Data.Profunctor.Strong.Tambara p)
instance Data.Profunctor.Unsafe.Profunctor p => GHC.Base.Functor (Data.Profunctor.Strong.Tambara p a)
instance (Data.Profunctor.Unsafe.Profunctor p, Control.Arrow.Arrow p) => GHC.Base.Applicative (Data.Profunctor.Strong.Tambara p a)
instance (Data.Profunctor.Unsafe.Profunctor p, Control.Arrow.ArrowPlus p) => GHC.Base.Alternative (Data.Profunctor.Strong.Tambara p a)
instance Control.Arrow.ArrowPlus p => GHC.Base.Monoid (Data.Profunctor.Strong.Tambara p a b)
instance Data.Profunctor.Unsafe.Profunctor (Data.Profunctor.Strong.Pastro p)
instance Data.Profunctor.Monad.ProfunctorFunctor Data.Profunctor.Strong.Pastro
instance Data.Profunctor.Monad.ProfunctorMonad Data.Profunctor.Strong.Pastro
instance Data.Profunctor.Adjunction.ProfunctorAdjunction Data.Profunctor.Strong.Pastro Data.Profunctor.Strong.Tambara
instance Data.Profunctor.Strong.Strong (Data.Profunctor.Strong.Pastro p)
instance Data.Profunctor.Strong.Costrong (->)
instance GHC.Base.Functor f => Data.Profunctor.Strong.Costrong (Data.Profunctor.Types.Costar f)
instance Data.Profunctor.Strong.Costrong Data.Tagged.Tagged
instance Control.Arrow.ArrowLoop p => Data.Profunctor.Strong.Costrong (Data.Profunctor.Types.WrappedArrow p)
instance Control.Monad.Fix.MonadFix m => Data.Profunctor.Strong.Costrong (Control.Arrow.Kleisli m)
instance GHC.Base.Functor f => Data.Profunctor.Strong.Costrong (Control.Comonad.Cokleisli f)
instance (GHC.Base.Functor f, Data.Profunctor.Strong.Costrong p) => Data.Profunctor.Strong.Costrong (Data.Bifunctor.Tannen.Tannen f p)
instance (Data.Profunctor.Strong.Costrong p, Data.Profunctor.Strong.Costrong q) => Data.Profunctor.Strong.Costrong (Data.Bifunctor.Product.Product p q)
instance Data.Profunctor.Unsafe.Profunctor (Data.Profunctor.Strong.Cotambara p)
instance Data.Profunctor.Monad.ProfunctorFunctor Data.Profunctor.Strong.Cotambara
instance Data.Profunctor.Monad.ProfunctorComonad Data.Profunctor.Strong.Cotambara
instance Data.Profunctor.Strong.Costrong (Data.Profunctor.Strong.Cotambara p)
instance GHC.Base.Functor (Data.Profunctor.Strong.Cotambara p a)
instance Data.Profunctor.Unsafe.Profunctor (Data.Profunctor.Strong.Copastro p)
instance Data.Profunctor.Adjunction.ProfunctorAdjunction Data.Profunctor.Strong.Copastro Data.Profunctor.Strong.Cotambara
instance Data.Profunctor.Monad.ProfunctorFunctor Data.Profunctor.Strong.Copastro
instance Data.Profunctor.Monad.ProfunctorMonad Data.Profunctor.Strong.Copastro
instance Data.Profunctor.Strong.Costrong (Data.Profunctor.Strong.Copastro p)


module Data.Profunctor.Choice

-- | The generalization of <a>Costar</a> of <a>Functor</a> that is strong
--   with respect to <a>Either</a>.
--   
--   Note: This is also a notion of strength, except with regards to
--   another monoidal structure that we can choose to equip Hask with: the
--   cocartesian coproduct.
class Profunctor p => Choice p where left' = dimap (either Right Left) (either Right Left) . right' right' = dimap (either Right Left) (either Right Left) . left'
left' :: Choice p => p a b -> p (Either a c) (Either b c)
right' :: Choice p => p a b -> p (Either c a) (Either c b)

-- | TambaraSum is cofreely adjoins strength with respect to Either.
--   
--   Note: this is not dual to <a>Tambara</a>. It is <a>Tambara</a> with
--   respect to a different tensor.
newtype TambaraSum p a b
TambaraSum :: (forall c. p (Either a c) (Either b c)) -> TambaraSum p a b
[runTambaraSum] :: TambaraSum p a b -> forall c. p (Either a c) (Either b c)

-- | <pre>
--   <a>tambaraSum</a> <a>.</a> <a>untambaraSum</a> ≡ <a>id</a>
--   <a>untambaraSum</a> <a>.</a> <a>tambaraSum</a> ≡ <a>id</a>
--   </pre>
tambaraSum :: Choice p => (p :-> q) -> p :-> TambaraSum q

-- | <pre>
--   <a>tambaraSum</a> <a>.</a> <a>untambaraSum</a> ≡ <a>id</a>
--   <a>untambaraSum</a> <a>.</a> <a>tambaraSum</a> ≡ <a>id</a>
--   </pre>
untambaraSum :: Profunctor q => (p :-> TambaraSum q) -> p :-> q

-- | PastroSum -| TambaraSum
--   
--   PastroSum freely constructs strength with respect to Either.
data PastroSum p a b
[PastroSum] :: (Either y z -> b) -> p x y -> (a -> Either x z) -> PastroSum p a b
class Profunctor p => Cochoice p where unleft = unright . dimap (either Right Left) (either Right Left) unright = unleft . dimap (either Right Left) (either Right Left)
unleft :: Cochoice p => p (Either a d) (Either b d) -> p a b
unright :: Cochoice p => p (Either d a) (Either d b) -> p a b

-- | <a>CotambaraSum</a> cofreely constructs costrength with respect to
--   <a>Either</a> (aka <a>Choice</a>)
data CotambaraSum q a b
[CotambaraSum] :: Cochoice r => (r :-> q) -> r a b -> CotambaraSum q a b

-- | <pre>
--   <a>cotambaraSum</a> <a>.</a> <a>uncotambaraSum</a> ≡ <a>id</a>
--   <a>uncotambaraSum</a> <a>.</a> <a>cotambaraSum</a> ≡ <a>id</a>
--   </pre>
cotambaraSum :: Cochoice p => (p :-> q) -> p :-> CotambaraSum q

-- | <pre>
--   <a>cotambaraSum</a> <a>.</a> <a>uncotambaraSum</a> ≡ <a>id</a>
--   <a>uncotambaraSum</a> <a>.</a> <a>cotambaraSum</a> ≡ <a>id</a>
--   </pre>
uncotambaraSum :: Profunctor q => (p :-> CotambaraSum q) -> p :-> q

-- | CopastroSum -| CotambaraSum
--   
--   <a>CopastroSum</a> freely constructs costrength with respect to
--   <a>Either</a> (aka <a>Choice</a>)
newtype CopastroSum p a b
CopastroSum :: (forall r. Cochoice r => (forall x y. p x y -> r x y) -> r a b) -> CopastroSum p a b
[runCopastroSum] :: CopastroSum p a b -> forall r. Cochoice r => (forall x y. p x y -> r x y) -> r a b
instance Data.Profunctor.Choice.Choice (->)
instance GHC.Base.Monad m => Data.Profunctor.Choice.Choice (Control.Arrow.Kleisli m)
instance GHC.Base.Applicative f => Data.Profunctor.Choice.Choice (Data.Profunctor.Types.Star f)
instance Control.Comonad.Comonad w => Data.Profunctor.Choice.Choice (Control.Comonad.Cokleisli w)
instance Data.Traversable.Traversable w => Data.Profunctor.Choice.Choice (Data.Profunctor.Types.Costar w)
instance Data.Profunctor.Choice.Choice Data.Tagged.Tagged
instance Control.Arrow.ArrowChoice p => Data.Profunctor.Choice.Choice (Data.Profunctor.Types.WrappedArrow p)
instance GHC.Base.Monoid r => Data.Profunctor.Choice.Choice (Data.Profunctor.Types.Forget r)
instance GHC.Base.Functor f => Data.Profunctor.Choice.Choice (Data.Bifunctor.Joker.Joker f)
instance (Data.Profunctor.Choice.Choice p, Data.Profunctor.Choice.Choice q) => Data.Profunctor.Choice.Choice (Data.Bifunctor.Product.Product p q)
instance (GHC.Base.Functor f, Data.Profunctor.Choice.Choice p) => Data.Profunctor.Choice.Choice (Data.Bifunctor.Tannen.Tannen f p)
instance Data.Profunctor.Choice.Choice p => Data.Profunctor.Choice.Choice (Data.Profunctor.Strong.Tambara p)
instance Data.Profunctor.Monad.ProfunctorFunctor Data.Profunctor.Choice.TambaraSum
instance Data.Profunctor.Monad.ProfunctorComonad Data.Profunctor.Choice.TambaraSum
instance Data.Profunctor.Unsafe.Profunctor p => Data.Profunctor.Unsafe.Profunctor (Data.Profunctor.Choice.TambaraSum p)
instance Data.Profunctor.Unsafe.Profunctor p => Data.Profunctor.Choice.Choice (Data.Profunctor.Choice.TambaraSum p)
instance Control.Category.Category p => Control.Category.Category (Data.Profunctor.Choice.TambaraSum p)
instance Data.Profunctor.Unsafe.Profunctor p => GHC.Base.Functor (Data.Profunctor.Choice.TambaraSum p a)
instance Data.Profunctor.Unsafe.Profunctor (Data.Profunctor.Choice.PastroSum p)
instance Data.Profunctor.Adjunction.ProfunctorAdjunction Data.Profunctor.Choice.PastroSum Data.Profunctor.Choice.TambaraSum
instance Data.Profunctor.Monad.ProfunctorFunctor Data.Profunctor.Choice.PastroSum
instance Data.Profunctor.Monad.ProfunctorMonad Data.Profunctor.Choice.PastroSum
instance Data.Profunctor.Choice.Choice (Data.Profunctor.Choice.PastroSum p)
instance Data.Profunctor.Choice.Cochoice (->)
instance GHC.Base.Applicative f => Data.Profunctor.Choice.Cochoice (Data.Profunctor.Types.Costar f)
instance Data.Traversable.Traversable f => Data.Profunctor.Choice.Cochoice (Data.Profunctor.Types.Star f)
instance (GHC.Base.Functor f, Data.Profunctor.Choice.Cochoice p) => Data.Profunctor.Choice.Cochoice (Data.Bifunctor.Tannen.Tannen f p)
instance (Data.Profunctor.Choice.Cochoice p, Data.Profunctor.Choice.Cochoice q) => Data.Profunctor.Choice.Cochoice (Data.Bifunctor.Product.Product p q)
instance Data.Profunctor.Unsafe.Profunctor (Data.Profunctor.Choice.CotambaraSum p)
instance Data.Profunctor.Monad.ProfunctorFunctor Data.Profunctor.Choice.CotambaraSum
instance Data.Profunctor.Monad.ProfunctorComonad Data.Profunctor.Choice.CotambaraSum
instance Data.Profunctor.Choice.Cochoice (Data.Profunctor.Choice.CotambaraSum p)
instance GHC.Base.Functor (Data.Profunctor.Choice.CotambaraSum p a)
instance Data.Profunctor.Unsafe.Profunctor (Data.Profunctor.Choice.CopastroSum p)
instance Data.Profunctor.Adjunction.ProfunctorAdjunction Data.Profunctor.Choice.CopastroSum Data.Profunctor.Choice.CotambaraSum
instance Data.Profunctor.Monad.ProfunctorFunctor Data.Profunctor.Choice.CopastroSum
instance Data.Profunctor.Monad.ProfunctorMonad Data.Profunctor.Choice.CopastroSum
instance Data.Profunctor.Choice.Cochoice (Data.Profunctor.Choice.CopastroSum p)


module Data.Profunctor.Closed

-- | A strong profunctor allows the monoidal structure to pass through.
--   
--   A closed profunctor allows the closed structure to pass through.
class Profunctor p => Closed p
closed :: Closed p => p a b -> p (x -> a) (x -> b)

-- | <a>Closure</a> adjoins a <a>Closed</a> structure to any
--   <a>Profunctor</a>.
--   
--   Analogous to <a>Tambara</a> for <a>Strong</a>.
newtype Closure p a b
Closure :: (forall x. p (x -> a) (x -> b)) -> Closure p a b
[runClosure] :: Closure p a b -> forall x. p (x -> a) (x -> b)

-- | <pre>
--   <a>close</a> <a>.</a> <a>unclose</a> ≡ <a>id</a>
--   <a>unclose</a> <a>.</a> <a>close</a> ≡ <a>id</a>
--   </pre>
close :: Closed p => (p :-> q) -> p :-> Closure q

-- | <pre>
--   <a>close</a> <a>.</a> <a>unclose</a> ≡ <a>id</a>
--   <a>unclose</a> <a>.</a> <a>close</a> ≡ <a>id</a>
--   </pre>
unclose :: Profunctor q => (p :-> Closure q) -> p :-> q
data Environment p a b
[Environment] :: ((z -> y) -> b) -> p x y -> (a -> z -> x) -> Environment p a b
curry' :: Closed p => p (a, b) c -> p a (b -> c)
instance Data.Profunctor.Closed.Closed Data.Tagged.Tagged
instance Data.Profunctor.Closed.Closed (->)
instance GHC.Base.Functor f => Data.Profunctor.Closed.Closed (Data.Profunctor.Types.Costar f)
instance GHC.Base.Functor f => Data.Profunctor.Closed.Closed (Control.Comonad.Cokleisli f)
instance Data.Distributive.Distributive f => Data.Profunctor.Closed.Closed (Data.Profunctor.Types.Star f)
instance (Data.Distributive.Distributive f, GHC.Base.Monad f) => Data.Profunctor.Closed.Closed (Control.Arrow.Kleisli f)
instance (Data.Profunctor.Closed.Closed p, Data.Profunctor.Closed.Closed q) => Data.Profunctor.Closed.Closed (Data.Bifunctor.Product.Product p q)
instance (GHC.Base.Functor f, Data.Profunctor.Closed.Closed p) => Data.Profunctor.Closed.Closed (Data.Bifunctor.Tannen.Tannen f p)
instance Data.Profunctor.Unsafe.Profunctor p => Data.Profunctor.Unsafe.Profunctor (Data.Profunctor.Closed.Closure p)
instance Data.Profunctor.Monad.ProfunctorFunctor Data.Profunctor.Closed.Closure
instance Data.Profunctor.Monad.ProfunctorComonad Data.Profunctor.Closed.Closure
instance Data.Profunctor.Unsafe.Profunctor p => Data.Profunctor.Closed.Closed (Data.Profunctor.Closed.Closure p)
instance Data.Profunctor.Strong.Strong p => Data.Profunctor.Strong.Strong (Data.Profunctor.Closed.Closure p)
instance Control.Category.Category p => Control.Category.Category (Data.Profunctor.Closed.Closure p)
instance Control.Arrow.Arrow p => Control.Arrow.Arrow (Data.Profunctor.Closed.Closure p)
instance Control.Arrow.ArrowLoop p => Control.Arrow.ArrowLoop (Data.Profunctor.Closed.Closure p)
instance Control.Arrow.ArrowZero p => Control.Arrow.ArrowZero (Data.Profunctor.Closed.Closure p)
instance Control.Arrow.ArrowPlus p => Control.Arrow.ArrowPlus (Data.Profunctor.Closed.Closure p)
instance Data.Profunctor.Unsafe.Profunctor p => GHC.Base.Functor (Data.Profunctor.Closed.Closure p a)
instance (Data.Profunctor.Unsafe.Profunctor p, Control.Arrow.Arrow p) => GHC.Base.Applicative (Data.Profunctor.Closed.Closure p a)
instance (Data.Profunctor.Unsafe.Profunctor p, Control.Arrow.ArrowPlus p) => GHC.Base.Alternative (Data.Profunctor.Closed.Closure p a)
instance (Data.Profunctor.Unsafe.Profunctor p, Control.Arrow.Arrow p, GHC.Base.Monoid b) => GHC.Base.Monoid (Data.Profunctor.Closed.Closure p a b)
instance Data.Profunctor.Unsafe.Profunctor (Data.Profunctor.Closed.Environment p)
instance Data.Profunctor.Monad.ProfunctorFunctor Data.Profunctor.Closed.Environment
instance Data.Profunctor.Monad.ProfunctorMonad Data.Profunctor.Closed.Environment
instance Data.Profunctor.Adjunction.ProfunctorAdjunction Data.Profunctor.Closed.Environment Data.Profunctor.Closed.Closure
instance Data.Profunctor.Closed.Closed (Data.Profunctor.Closed.Environment p)

module Data.Profunctor.Traversing

-- | Note: Definitions in terms of <a>wander</a> are much more efficient!
class (Choice p, Strong p) => Traversing p where traverse' = wander traverse wander f pab = dimap (\ s -> Baz $ \ afb -> f afb s) sold (traverse' pab)
traverse' :: (Traversing p, Traversable f) => p a b -> p (f a) (f b)
wander :: Traversing p => (forall f. Applicative f => (a -> f b) -> s -> f t) -> p a b -> p s t
newtype CofreeTraversing p a b
CofreeTraversing :: (forall f. Traversable f => p (f a) (f b)) -> CofreeTraversing p a b
[runCofreeTraversing] :: CofreeTraversing p a b -> forall f. Traversable f => p (f a) (f b)

-- | <pre>
--   FreeTraversing -| CofreeTraversing
--   </pre>
data FreeTraversing p a b
[FreeTraversing] :: Traversable f => (f y -> b) -> p x y -> (a -> f x) -> FreeTraversing p a b
firstTraversing :: Traversing p => p a b -> p (a, c) (b, c)
secondTraversing :: Traversing p => p a b -> p (c, a) (c, b)
leftTraversing :: Traversing p => p a b -> p (Either a c) (Either b c)
rightTraversing :: Traversing p => p a b -> p (Either c a) (Either c b)
instance GHC.Base.Functor (Data.Profunctor.Traversing.Baz t b)
instance GHC.Base.Functor (Data.Profunctor.Traversing.Bazaar a b)
instance GHC.Base.Applicative (Data.Profunctor.Traversing.Bazaar a b)
instance Data.Profunctor.Unsafe.Profunctor (Data.Profunctor.Traversing.Bazaar a)
instance Data.Foldable.Foldable (Data.Profunctor.Traversing.Baz t b)
instance Data.Traversable.Traversable (Data.Profunctor.Traversing.Baz t b)
instance Data.Profunctor.Unsafe.Profunctor (Data.Profunctor.Traversing.Baz t)
instance Data.Profunctor.Traversing.Traversing (->)
instance GHC.Base.Monad m => Data.Profunctor.Traversing.Traversing (Control.Arrow.Kleisli m)
instance GHC.Base.Applicative m => Data.Profunctor.Traversing.Traversing (Data.Profunctor.Types.Star m)
instance Data.Profunctor.Unsafe.Profunctor p => Data.Profunctor.Unsafe.Profunctor (Data.Profunctor.Traversing.CofreeTraversing p)
instance Data.Profunctor.Unsafe.Profunctor p => Data.Profunctor.Strong.Strong (Data.Profunctor.Traversing.CofreeTraversing p)
instance Data.Profunctor.Unsafe.Profunctor p => Data.Profunctor.Choice.Choice (Data.Profunctor.Traversing.CofreeTraversing p)
instance Data.Profunctor.Unsafe.Profunctor p => Data.Profunctor.Traversing.Traversing (Data.Profunctor.Traversing.CofreeTraversing p)
instance Data.Profunctor.Monad.ProfunctorFunctor Data.Profunctor.Traversing.CofreeTraversing
instance Data.Profunctor.Monad.ProfunctorComonad Data.Profunctor.Traversing.CofreeTraversing
instance Data.Profunctor.Unsafe.Profunctor (Data.Profunctor.Traversing.FreeTraversing p)
instance Data.Profunctor.Strong.Strong (Data.Profunctor.Traversing.FreeTraversing p)
instance Data.Profunctor.Choice.Choice (Data.Profunctor.Traversing.FreeTraversing p)
instance Data.Profunctor.Traversing.Traversing (Data.Profunctor.Traversing.FreeTraversing p)
instance Data.Profunctor.Monad.ProfunctorFunctor Data.Profunctor.Traversing.FreeTraversing
instance Data.Profunctor.Monad.ProfunctorMonad Data.Profunctor.Traversing.FreeTraversing

module Data.Profunctor.Mapping
class (Traversing p, Closed p) => Mapping p
map' :: (Mapping p, Functor f) => p a b -> p (f a) (f b)
newtype CofreeMapping p a b
CofreeMapping :: (forall f. Functor f => p (f a) (f b)) -> CofreeMapping p a b
[runCofreeMapping] :: CofreeMapping p a b -> forall f. Functor f => p (f a) (f b)

-- | <pre>
--   FreeMapping -| CofreeMapping
--   </pre>
data FreeMapping p a b
[FreeMapping] :: Functor f => (f y -> b) -> p x y -> (a -> f x) -> FreeMapping p a b
traverseMapping :: (Mapping p, Functor f) => p a b -> p (f a) (f b)
closedMapping :: Mapping p => p a b -> p (x -> a) (x -> b)
instance Data.Profunctor.Mapping.Mapping (->)
instance (GHC.Base.Monad m, Data.Distributive.Distributive m) => Data.Profunctor.Mapping.Mapping (Control.Arrow.Kleisli m)
instance (GHC.Base.Applicative m, Data.Distributive.Distributive m) => Data.Profunctor.Mapping.Mapping (Data.Profunctor.Types.Star m)
instance Data.Profunctor.Unsafe.Profunctor p => Data.Profunctor.Unsafe.Profunctor (Data.Profunctor.Mapping.CofreeMapping p)
instance Data.Profunctor.Unsafe.Profunctor p => Data.Profunctor.Strong.Strong (Data.Profunctor.Mapping.CofreeMapping p)
instance Data.Profunctor.Unsafe.Profunctor p => Data.Profunctor.Choice.Choice (Data.Profunctor.Mapping.CofreeMapping p)
instance Data.Profunctor.Unsafe.Profunctor p => Data.Profunctor.Closed.Closed (Data.Profunctor.Mapping.CofreeMapping p)
instance Data.Profunctor.Unsafe.Profunctor p => Data.Profunctor.Traversing.Traversing (Data.Profunctor.Mapping.CofreeMapping p)
instance Data.Profunctor.Unsafe.Profunctor p => Data.Profunctor.Mapping.Mapping (Data.Profunctor.Mapping.CofreeMapping p)
instance Data.Profunctor.Monad.ProfunctorFunctor Data.Profunctor.Mapping.CofreeMapping
instance Data.Profunctor.Monad.ProfunctorComonad Data.Profunctor.Mapping.CofreeMapping
instance Data.Profunctor.Unsafe.Profunctor (Data.Profunctor.Mapping.FreeMapping p)
instance Data.Profunctor.Strong.Strong (Data.Profunctor.Mapping.FreeMapping p)
instance Data.Profunctor.Choice.Choice (Data.Profunctor.Mapping.FreeMapping p)
instance Data.Profunctor.Closed.Closed (Data.Profunctor.Mapping.FreeMapping p)
instance Data.Profunctor.Traversing.Traversing (Data.Profunctor.Mapping.FreeMapping p)
instance Data.Profunctor.Mapping.Mapping (Data.Profunctor.Mapping.FreeMapping p)
instance Data.Profunctor.Monad.ProfunctorFunctor Data.Profunctor.Mapping.FreeMapping
instance Data.Profunctor.Monad.ProfunctorMonad Data.Profunctor.Mapping.FreeMapping


-- | For a good explanation of profunctors in Haskell see Dan Piponi's
--   article:
--   
--   <a>http://blog.sigfpe.com/2011/07/profunctors-in-haskell.html</a>
--   
--   For more information on strength and costrength, see:
--   
--   <a>http://comonad.com/reader/2008/deriving-strength-from-laziness/</a>
module Data.Profunctor

-- | Formally, the class <a>Profunctor</a> represents a profunctor from
--   <tt>Hask</tt> -&gt; <tt>Hask</tt>.
--   
--   Intuitively it is a bifunctor where the first argument is
--   contravariant and the second argument is covariant.
--   
--   You can define a <a>Profunctor</a> by either defining <a>dimap</a> or
--   by defining both <a>lmap</a> and <a>rmap</a>.
--   
--   If you supply <a>dimap</a>, you should ensure that:
--   
--   <pre>
--   <a>dimap</a> <a>id</a> <a>id</a> ≡ <a>id</a>
--   </pre>
--   
--   If you supply <a>lmap</a> and <a>rmap</a>, ensure:
--   
--   <pre>
--   <a>lmap</a> <a>id</a> ≡ <a>id</a>
--   <a>rmap</a> <a>id</a> ≡ <a>id</a>
--   </pre>
--   
--   If you supply both, you should also ensure:
--   
--   <pre>
--   <a>dimap</a> f g ≡ <a>lmap</a> f <a>.</a> <a>rmap</a> g
--   </pre>
--   
--   These ensure by parametricity:
--   
--   <pre>
--   <a>dimap</a> (f <a>.</a> g) (h <a>.</a> i) ≡ <a>dimap</a> g h <a>.</a> <a>dimap</a> f i
--   <a>lmap</a> (f <a>.</a> g) ≡ <a>lmap</a> g <a>.</a> <a>lmap</a> f
--   <a>rmap</a> (f <a>.</a> g) ≡ <a>rmap</a> f <a>.</a> <a>rmap</a> g
--   </pre>
class Profunctor p where dimap f g = lmap f . rmap g lmap f = dimap f id rmap = dimap id (#.) = \ f -> \ p -> p `seq` rmap f p (.#) = \ p -> p `seq` \ f -> lmap f p

-- | Map over both arguments at the same time.
--   
--   <pre>
--   <a>dimap</a> f g ≡ <a>lmap</a> f <a>.</a> <a>rmap</a> g
--   </pre>
dimap :: Profunctor p => (a -> b) -> (c -> d) -> p b c -> p a d

-- | Map the first argument contravariantly.
--   
--   <pre>
--   <a>lmap</a> f ≡ <a>dimap</a> f <a>id</a>
--   </pre>
lmap :: Profunctor p => (a -> b) -> p b c -> p a c

-- | Map the second argument covariantly.
--   
--   <pre>
--   <a>rmap</a> ≡ <a>dimap</a> <a>id</a>
--   </pre>
rmap :: Profunctor p => (b -> c) -> p a b -> p a c

-- | Generalizing <a>Star</a> of a strong <a>Functor</a>
--   
--   <i>Note:</i> Every <a>Functor</a> in Haskell is strong with respect to
--   <tt>(,)</tt>.
--   
--   This describes profunctor strength with respect to the product
--   structure of Hask.
--   
--   <a>http://www-kb.is.s.u-tokyo.ac.jp/~asada/papers/arrStrMnd.pdf</a>
class Profunctor p => Strong p where first' = dimap swap swap . second' second' = dimap swap swap . first'
first' :: Strong p => p a b -> p (a, c) (b, c)
second' :: Strong p => p a b -> p (c, a) (c, b)
uncurry' :: Strong p => p a (b -> c) -> p (a, b) c

-- | The generalization of <a>Costar</a> of <a>Functor</a> that is strong
--   with respect to <a>Either</a>.
--   
--   Note: This is also a notion of strength, except with regards to
--   another monoidal structure that we can choose to equip Hask with: the
--   cocartesian coproduct.
class Profunctor p => Choice p where left' = dimap (either Right Left) (either Right Left) . right' right' = dimap (either Right Left) (either Right Left) . left'
left' :: Choice p => p a b -> p (Either a c) (Either b c)
right' :: Choice p => p a b -> p (Either c a) (Either c b)

-- | A strong profunctor allows the monoidal structure to pass through.
--   
--   A closed profunctor allows the closed structure to pass through.
class Profunctor p => Closed p
closed :: Closed p => p a b -> p (x -> a) (x -> b)
curry' :: Closed p => p (a, b) c -> p a (b -> c)
class (Traversing p, Closed p) => Mapping p
map' :: (Mapping p, Functor f) => p a b -> p (f a) (f b)

-- | Analogous to <a>ArrowLoop</a>, <a>loop</a> = <a>unfirst</a>
class Profunctor p => Costrong p where unfirst = unsecond . dimap swap swap unsecond = unfirst . dimap swap swap
unfirst :: Costrong p => p (a, d) (b, d) -> p a b
unsecond :: Costrong p => p (d, a) (d, b) -> p a b
class Profunctor p => Cochoice p where unleft = unright . dimap (either Right Left) (either Right Left) unright = unleft . dimap (either Right Left) (either Right Left)
unleft :: Cochoice p => p (Either a d) (Either b d) -> p a b
unright :: Cochoice p => p (Either d a) (Either d b) -> p a b

-- | Lift a <a>Functor</a> into a <a>Profunctor</a> (forwards).
newtype Star f d c
Star :: (d -> f c) -> Star f d c
[runStar] :: Star f d c -> d -> f c

-- | Lift a <a>Functor</a> into a <a>Profunctor</a> (backwards).
newtype Costar f d c
Costar :: (f d -> c) -> Costar f d c
[runCostar] :: Costar f d c -> f d -> c

-- | Wrap an arrow for use as a <a>Profunctor</a>.
newtype WrappedArrow p a b
WrapArrow :: p a b -> WrappedArrow p a b
[unwrapArrow] :: WrappedArrow p a b -> p a b
newtype Forget r a b
Forget :: (a -> r) -> Forget r a b
[runForget] :: Forget r a b -> a -> r
type (:->) p q = forall a b. p a b -> q a b


module Data.Profunctor.Cayley
newtype Cayley f p a b
Cayley :: f (p a b) -> Cayley f p a b
[runCayley] :: Cayley f p a b -> f (p a b)

-- | Cayley transforms Monads in <tt>Hask</tt> into monads on <tt>Prof</tt>

-- | Cayley transforms Comonads in <tt>Hask</tt> into comonads on
--   <tt>Prof</tt>
instance GHC.Base.Functor f => Data.Profunctor.Monad.ProfunctorFunctor (Data.Profunctor.Cayley.Cayley f)
instance (GHC.Base.Functor f, GHC.Base.Monad f) => Data.Profunctor.Monad.ProfunctorMonad (Data.Profunctor.Cayley.Cayley f)
instance Control.Comonad.Comonad f => Data.Profunctor.Monad.ProfunctorComonad (Data.Profunctor.Cayley.Cayley f)
instance (GHC.Base.Functor f, Data.Profunctor.Unsafe.Profunctor p) => Data.Profunctor.Unsafe.Profunctor (Data.Profunctor.Cayley.Cayley f p)
instance (GHC.Base.Functor f, Data.Profunctor.Strong.Strong p) => Data.Profunctor.Strong.Strong (Data.Profunctor.Cayley.Cayley f p)
instance (GHC.Base.Functor f, Data.Profunctor.Choice.Choice p) => Data.Profunctor.Choice.Choice (Data.Profunctor.Cayley.Cayley f p)
instance (GHC.Base.Applicative f, Control.Category.Category p) => Control.Category.Category (Data.Profunctor.Cayley.Cayley f p)
instance (GHC.Base.Applicative f, Control.Arrow.Arrow p) => Control.Arrow.Arrow (Data.Profunctor.Cayley.Cayley f p)
instance (GHC.Base.Applicative f, Control.Arrow.ArrowChoice p) => Control.Arrow.ArrowChoice (Data.Profunctor.Cayley.Cayley f p)
instance (GHC.Base.Applicative f, Control.Arrow.ArrowLoop p) => Control.Arrow.ArrowLoop (Data.Profunctor.Cayley.Cayley f p)
instance (GHC.Base.Applicative f, Control.Arrow.ArrowZero p) => Control.Arrow.ArrowZero (Data.Profunctor.Cayley.Cayley f p)
instance (GHC.Base.Applicative f, Control.Arrow.ArrowPlus p) => Control.Arrow.ArrowPlus (Data.Profunctor.Cayley.Cayley f p)


module Data.Profunctor.Sieve

-- | A <a>Profunctor</a> <tt>p</tt> is a <a>Sieve</a> <b>on</b> <tt>f</tt>
--   if it is a subprofunctor of <tt><a>Star</a> f</tt>.
--   
--   That is to say it is a subset of <tt>Hom(-,f=)</tt> closed under
--   <a>lmap</a> and <a>rmap</a>.
--   
--   Alternately, you can view it as a sieve <b>in</b> the comma category
--   <tt>Hask/f</tt>.
class (Profunctor p, Functor f) => Sieve p f | p -> f
sieve :: Sieve p f => p a b -> a -> f b

-- | A <a>Profunctor</a> <tt>p</tt> is a <a>Cosieve</a> <b>on</b>
--   <tt>f</tt> if it is a subprofunctor of <tt><a>Costar</a> f</tt>.
--   
--   That is to say it is a subset of <tt>Hom(f-,=)</tt> closed under
--   <a>lmap</a> and <a>rmap</a>.
--   
--   Alternately, you can view it as a cosieve <b>in</b> the comma category
--   <tt>f/Hask</tt>.
class (Profunctor p, Functor f) => Cosieve p f | p -> f
cosieve :: Cosieve p f => p a b -> f a -> b
instance Data.Profunctor.Sieve.Sieve (->) Data.Functor.Identity.Identity
instance (GHC.Base.Monad m, GHC.Base.Functor m) => Data.Profunctor.Sieve.Sieve (Control.Arrow.Kleisli m) m
instance GHC.Base.Functor f => Data.Profunctor.Sieve.Sieve (Data.Profunctor.Types.Star f) f
instance Data.Profunctor.Sieve.Sieve (Data.Profunctor.Types.Forget r) (Data.Functor.Const.Const r)
instance Data.Profunctor.Sieve.Cosieve (->) Data.Functor.Identity.Identity
instance GHC.Base.Functor w => Data.Profunctor.Sieve.Cosieve (Control.Comonad.Cokleisli w) w
instance Data.Profunctor.Sieve.Cosieve Data.Tagged.Tagged Data.Proxy.Proxy
instance GHC.Base.Functor f => Data.Profunctor.Sieve.Cosieve (Data.Profunctor.Types.Costar f) f


module Data.Profunctor.Rep

-- | A <a>Profunctor</a> <tt>p</tt> is <a>Representable</a> if there exists
--   a <a>Functor</a> <tt>f</tt> such that <tt>p d c</tt> is isomorphic to
--   <tt>d -&gt; f c</tt>.
class (Sieve p (Rep p), Strong p) => Representable p where type Rep p :: * -> * where {
    type family Rep p :: * -> *;
}
tabulate :: Representable p => (d -> Rep p c) -> p d c

-- | <a>tabulate</a> and <a>sieve</a> form two halves of an isomorphism.
--   
--   This can be used with the combinators from the <tt>lens</tt> package.
--   
--   <pre>
--   <a>tabulated</a> :: <a>Representable</a> p =&gt; <tt>Iso'</tt> (d -&gt; <a>Rep</a> p c) (p d c)
--   </pre>
tabulated :: (Representable p, Representable q) => Iso (d -> Rep p c) (d' -> Rep q c') (p d c) (q d' c')

-- | Default definition for <a>first'</a> given that p is
--   <a>Representable</a>.
firstRep :: Representable p => p a b -> p (a, c) (b, c)

-- | Default definition for <a>second'</a> given that p is
--   <a>Representable</a>.
secondRep :: Representable p => p a b -> p (c, a) (c, b)

-- | A <a>Profunctor</a> <tt>p</tt> is <a>Corepresentable</a> if there
--   exists a <a>Functor</a> <tt>f</tt> such that <tt>p d c</tt> is
--   isomorphic to <tt>f d -&gt; c</tt>.
class (Cosieve p (Corep p), Costrong p) => Corepresentable p where type Corep p :: * -> * where {
    type family Corep p :: * -> *;
}
cotabulate :: Corepresentable p => (Corep p d -> c) -> p d c

-- | <a>cotabulate</a> and <a>cosieve</a> form two halves of an
--   isomorphism.
--   
--   This can be used with the combinators from the <tt>lens</tt> package.
--   
--   <pre>
--   <a>cotabulated</a> :: <a>Corep</a> f p =&gt; <tt>Iso'</tt> (f d -&gt; c) (p d c)
--   </pre>
cotabulated :: (Corepresentable p, Corepresentable q) => Iso (Corep p d -> c) (Corep q d' -> c') (p d c) (q d' c')

-- | Default definition for <a>unfirst</a> given that <tt>p</tt> is
--   <a>Corepresentable</a>.
unfirstCorep :: Corepresentable p => p (a, d) (b, d) -> p a b

-- | Default definition for <a>unsecond</a> given that <tt>p</tt> is
--   <a>Corepresentable</a>.
unsecondCorep :: Corepresentable p => p (d, a) (d, b) -> p a b

-- | Default definition for <a>closed</a> given that <tt>p</tt> is
--   <a>Corepresentable</a>
closedCorep :: Corepresentable p => p a b -> p (x -> a) (x -> b)

-- | <pre>
--   <a>Prep</a> -| <a>Star</a> :: [Hask, Hask] -&gt; Prof
--   </pre>
--   
--   This gives rise to a monad in <tt>Prof</tt>, <tt>('Star'.'Prep')</tt>,
--   and a comonad in <tt>[Hask,Hask]</tt> <tt>('Prep'.'Star')</tt>
data Prep p a
[Prep] :: x -> p x a -> Prep p a
prepAdj :: (forall a. Prep p a -> g a) -> p :-> Star g
unprepAdj :: (p :-> Star g) -> Prep p a -> g a
prepUnit :: p :-> Star (Prep p)
prepCounit :: Prep (Star f) a -> f a
newtype Coprep p a
Coprep :: (forall r. p a r -> r) -> Coprep p a
[runCoprep] :: Coprep p a -> forall r. p a r -> r

-- | <pre>
--   <a>Coprep</a> -| <a>Costar</a> :: [Hask, Hask]^op -&gt; Prof
--   </pre>
--   
--   Like all adjunctions this gives rise to a monad and a comonad.
--   
--   This gives rise to a monad on Prof <tt>('Costar'.'Coprep')</tt> and a
--   comonad on <tt>[Hask, Hask]^op</tt> given by
--   <tt>('Coprep'.'Costar')</tt> which is a monad in <tt>[Hask,Hask]</tt>
coprepAdj :: (forall a. f a -> Coprep p a) -> p :-> Costar f
uncoprepAdj :: (p :-> Costar f) -> f a -> Coprep p a
coprepUnit :: p :-> Costar (Coprep p)
coprepCounit :: f a -> Coprep (Costar f) a
instance Data.Profunctor.Rep.Representable (->)
instance (GHC.Base.Monad m, GHC.Base.Functor m) => Data.Profunctor.Rep.Representable (Control.Arrow.Kleisli m)
instance GHC.Base.Functor f => Data.Profunctor.Rep.Representable (Data.Profunctor.Types.Star f)
instance Data.Profunctor.Rep.Representable (Data.Profunctor.Types.Forget r)
instance Data.Profunctor.Rep.Corepresentable (->)
instance GHC.Base.Functor w => Data.Profunctor.Rep.Corepresentable (Control.Comonad.Cokleisli w)
instance Data.Profunctor.Rep.Corepresentable Data.Tagged.Tagged
instance GHC.Base.Functor f => Data.Profunctor.Rep.Corepresentable (Data.Profunctor.Types.Costar f)
instance Data.Profunctor.Unsafe.Profunctor p => GHC.Base.Functor (Data.Profunctor.Rep.Prep p)
instance (GHC.Base.Applicative (Data.Profunctor.Rep.Rep p), Data.Profunctor.Rep.Representable p) => GHC.Base.Applicative (Data.Profunctor.Rep.Prep p)
instance (GHC.Base.Monad (Data.Profunctor.Rep.Rep p), Data.Profunctor.Rep.Representable p) => GHC.Base.Monad (Data.Profunctor.Rep.Prep p)
instance Data.Profunctor.Unsafe.Profunctor p => GHC.Base.Functor (Data.Profunctor.Rep.Coprep p)


module Data.Profunctor.Composition

-- | <tt><a>Procompose</a> p q</tt> is the <a>Profunctor</a> composition of
--   the <a>Profunctor</a>s <tt>p</tt> and <tt>q</tt>.
--   
--   For a good explanation of <a>Profunctor</a> composition in Haskell see
--   Dan Piponi's article:
--   
--   <a>http://blog.sigfpe.com/2011/07/profunctors-in-haskell.html</a>
data Procompose p q d c
[Procompose] :: p x c -> q d x -> Procompose p q d c
procomposed :: Category p => Procompose p p a b -> p a b

-- | <tt>(-&gt;)</tt> functions as a lax identity for <a>Profunctor</a>
--   composition.
--   
--   This provides an <a>Iso</a> for the <tt>lens</tt> package that
--   witnesses the isomorphism between <tt><a>Procompose</a> (-&gt;) q d
--   c</tt> and <tt>q d c</tt>, which is the left identity law.
--   
--   <pre>
--   <a>idl</a> :: <a>Profunctor</a> q =&gt; Iso' (<a>Procompose</a> (-&gt;) q d c) (q d c)
--   </pre>
idl :: Profunctor q => Iso (Procompose (->) q d c) (Procompose (->) r d' c') (q d c) (r d' c')

-- | <tt>(-&gt;)</tt> functions as a lax identity for <a>Profunctor</a>
--   composition.
--   
--   This provides an <a>Iso</a> for the <tt>lens</tt> package that
--   witnesses the isomorphism between <tt><a>Procompose</a> q (-&gt;) d
--   c</tt> and <tt>q d c</tt>, which is the right identity law.
--   
--   <pre>
--   <a>idr</a> :: <a>Profunctor</a> q =&gt; Iso' (<a>Procompose</a> q (-&gt;) d c) (q d c)
--   </pre>
idr :: Profunctor q => Iso (Procompose q (->) d c) (Procompose r (->) d' c') (q d c) (r d' c')

-- | The associator for <a>Profunctor</a> composition.
--   
--   This provides an <a>Iso</a> for the <tt>lens</tt> package that
--   witnesses the isomorphism between <tt><a>Procompose</a> p
--   (<a>Procompose</a> q r) a b</tt> and <tt><a>Procompose</a>
--   (<a>Procompose</a> p q) r a b</tt>, which arises because <tt>Prof</tt>
--   is only a bicategory, rather than a strict 2-category.
assoc :: Iso (Procompose p (Procompose q r) a b) (Procompose x (Procompose y z) a b) (Procompose (Procompose p q) r a b) (Procompose (Procompose x y) z a b)

-- | a <a>Category</a> that is also a <a>Profunctor</a> is a <a>Monoid</a>
--   in <tt>Prof</tt>
eta :: (Profunctor p, Category p) => (->) :-> p
mu :: Category p => Procompose p p :-> p

-- | <a>Profunctor</a> composition generalizes <a>Functor</a> composition
--   in two ways.
--   
--   This is the first, which shows that <tt>exists b. (a -&gt; f b, b
--   -&gt; g c)</tt> is isomorphic to <tt>a -&gt; f (g c)</tt>.
--   
--   <pre>
--   <a>stars</a> :: <a>Functor</a> f =&gt; Iso' (<a>Procompose</a> (<a>Star</a> f) (<a>Star</a> g) d c) (<a>Star</a> (<a>Compose</a> f g) d c)
--   </pre>
stars :: Functor g => Iso (Procompose (Star f) (Star g) d c) (Procompose (Star f') (Star g') d' c') (Star (Compose g f) d c) (Star (Compose g' f') d' c')

-- | This is a variant on <a>stars</a> that uses <a>Kleisli</a> instead of
--   <a>Star</a>.
--   
--   <pre>
--   <a>kleislis</a> :: <a>Monad</a> f =&gt; Iso' (<a>Procompose</a> (<a>Kleisli</a> f) (<a>Kleisli</a> g) d c) (<a>Kleisli</a> (<a>Compose</a> f g) d c)
--   </pre>
kleislis :: Monad g => Iso (Procompose (Kleisli f) (Kleisli g) d c) (Procompose (Kleisli f') (Kleisli g') d' c') (Kleisli (Compose g f) d c) (Kleisli (Compose g' f') d' c')

-- | <a>Profunctor</a> composition generalizes <a>Functor</a> composition
--   in two ways.
--   
--   This is the second, which shows that <tt>exists b. (f a -&gt; b, g b
--   -&gt; c)</tt> is isomorphic to <tt>g (f a) -&gt; c</tt>.
--   
--   <pre>
--   <a>costars</a> :: <a>Functor</a> f =&gt; Iso' (<a>Procompose</a> (<a>Costar</a> f) (<a>Costar</a> g) d c) (<a>Costar</a> (<a>Compose</a> g f) d c)
--   </pre>
costars :: Functor f => Iso (Procompose (Costar f) (Costar g) d c) (Procompose (Costar f') (Costar g') d' c') (Costar (Compose f g) d c) (Costar (Compose f' g') d' c')

-- | This is a variant on <a>costars</a> that uses <a>Cokleisli</a> instead
--   of <a>Costar</a>.
--   
--   <pre>
--   <a>cokleislis</a> :: <a>Functor</a> f =&gt; Iso' (<a>Procompose</a> (<a>Cokleisli</a> f) (<a>Cokleisli</a> g) d c) (<a>Cokleisli</a> (<a>Compose</a> g f) d c)
--   </pre>
cokleislis :: Functor f => Iso (Procompose (Cokleisli f) (Cokleisli g) d c) (Procompose (Cokleisli f') (Cokleisli g') d' c') (Cokleisli (Compose f g) d c) (Cokleisli (Compose f' g') d' c')

-- | This represents the right Kan lift of a <a>Profunctor</a> <tt>q</tt>
--   along a <a>Profunctor</a> <tt>p</tt> in a limited version of the
--   2-category of Profunctors where the only object is the category Hask,
--   1-morphisms are profunctors composed and compose with Profunctor
--   composition, and 2-morphisms are just natural transformations.
newtype Rift p q a b
Rift :: (forall x. p b x -> q a x) -> Rift p q a b
[runRift] :: Rift p q a b -> forall x. p b x -> q a x

-- | The 2-morphism that defines a left Kan lift.
--   
--   Note: When <tt>p</tt> is right adjoint to <tt><a>Rift</a> p
--   (-&gt;)</tt> then <a>decomposeRift</a> is the <a>counit</a> of the
--   adjunction.
decomposeRift :: Procompose p (Rift p q) :-> q
instance Data.Profunctor.Monad.ProfunctorFunctor (Data.Profunctor.Composition.Procompose p)
instance Control.Category.Category p => Data.Profunctor.Monad.ProfunctorMonad (Data.Profunctor.Composition.Procompose p)
instance (Data.Profunctor.Unsafe.Profunctor p, Data.Profunctor.Unsafe.Profunctor q) => Data.Profunctor.Unsafe.Profunctor (Data.Profunctor.Composition.Procompose p q)
instance Data.Profunctor.Unsafe.Profunctor p => GHC.Base.Functor (Data.Profunctor.Composition.Procompose p q a)
instance (Data.Profunctor.Sieve.Sieve p f, Data.Profunctor.Sieve.Sieve q g) => Data.Profunctor.Sieve.Sieve (Data.Profunctor.Composition.Procompose p q) (Data.Functor.Compose.Compose g f)
instance (Data.Profunctor.Rep.Representable p, Data.Profunctor.Rep.Representable q) => Data.Profunctor.Rep.Representable (Data.Profunctor.Composition.Procompose p q)
instance (Data.Profunctor.Sieve.Cosieve p f, Data.Profunctor.Sieve.Cosieve q g) => Data.Profunctor.Sieve.Cosieve (Data.Profunctor.Composition.Procompose p q) (Data.Functor.Compose.Compose f g)
instance (Data.Profunctor.Rep.Corepresentable p, Data.Profunctor.Rep.Corepresentable q) => Data.Profunctor.Rep.Corepresentable (Data.Profunctor.Composition.Procompose p q)
instance (Data.Profunctor.Strong.Strong p, Data.Profunctor.Strong.Strong q) => Data.Profunctor.Strong.Strong (Data.Profunctor.Composition.Procompose p q)
instance (Data.Profunctor.Choice.Choice p, Data.Profunctor.Choice.Choice q) => Data.Profunctor.Choice.Choice (Data.Profunctor.Composition.Procompose p q)
instance (Data.Profunctor.Closed.Closed p, Data.Profunctor.Closed.Closed q) => Data.Profunctor.Closed.Closed (Data.Profunctor.Composition.Procompose p q)
instance (Data.Profunctor.Rep.Corepresentable p, Data.Profunctor.Rep.Corepresentable q) => Data.Profunctor.Strong.Costrong (Data.Profunctor.Composition.Procompose p q)
instance Data.Profunctor.Monad.ProfunctorFunctor (Data.Profunctor.Composition.Rift p)
instance Control.Category.Category p => Data.Profunctor.Monad.ProfunctorComonad (Data.Profunctor.Composition.Rift p)
instance (Data.Profunctor.Unsafe.Profunctor p, Data.Profunctor.Unsafe.Profunctor q) => Data.Profunctor.Unsafe.Profunctor (Data.Profunctor.Composition.Rift p q)
instance Data.Profunctor.Unsafe.Profunctor p => GHC.Base.Functor (Data.Profunctor.Composition.Rift p q a)
instance p ~ q => Control.Category.Category (Data.Profunctor.Composition.Rift p q)
instance Data.Profunctor.Adjunction.ProfunctorAdjunction (Data.Profunctor.Composition.Procompose p) (Data.Profunctor.Composition.Rift p)


module Data.Profunctor.Ran

-- | This represents the right Kan extension of a <a>Profunctor</a>
--   <tt>q</tt> along a <a>Profunctor</a> <tt>p</tt> in a limited version
--   of the 2-category of Profunctors where the only object is the category
--   Hask, 1-morphisms are profunctors composed and compose with Profunctor
--   composition, and 2-morphisms are just natural transformations.
newtype Ran p q a b
Ran :: (forall x. p x a -> q x b) -> Ran p q a b
[runRan] :: Ran p q a b -> forall x. p x a -> q x b

-- | The 2-morphism that defines a right Kan extension.
--   
--   Note: When <tt>q</tt> is left adjoint to <tt><a>Ran</a> q (-&gt;)</tt>
--   then <a>decomposeRan</a> is the <tt>counit</tt> of the adjunction.
decomposeRan :: Procompose (Ran q p) q :-> p
precomposeRan :: Profunctor q => Procompose q (Ran p (->)) :-> Ran p q
curryRan :: (Procompose p q :-> r) -> p :-> Ran q r
uncurryRan :: (p :-> Ran q r) -> Procompose p q :-> r

-- | This represents the right Kan extension of a <a>Profunctor</a>
--   <tt>p</tt> along itself. This provides a generalization of the
--   "difference list" trick to profunctors.
newtype Codensity p a b
Codensity :: (forall x. p x a -> p x b) -> Codensity p a b
[runCodensity] :: Codensity p a b -> forall x. p x a -> p x b
decomposeCodensity :: Procompose (Codensity p) p a b -> p a b
instance Data.Profunctor.Monad.ProfunctorFunctor (Data.Profunctor.Ran.Ran p)
instance Control.Category.Category p => Data.Profunctor.Monad.ProfunctorComonad (Data.Profunctor.Ran.Ran p)
instance (Data.Profunctor.Unsafe.Profunctor p, Data.Profunctor.Unsafe.Profunctor q) => Data.Profunctor.Unsafe.Profunctor (Data.Profunctor.Ran.Ran p q)
instance Data.Profunctor.Unsafe.Profunctor q => GHC.Base.Functor (Data.Profunctor.Ran.Ran p q a)
instance p ~ q => Control.Category.Category (Data.Profunctor.Ran.Ran p q)
instance Data.Profunctor.Unsafe.Profunctor p => Data.Profunctor.Unsafe.Profunctor (Data.Profunctor.Ran.Codensity p)
instance Data.Profunctor.Unsafe.Profunctor p => GHC.Base.Functor (Data.Profunctor.Ran.Codensity p a)
instance Control.Category.Category (Data.Profunctor.Ran.Codensity p)
