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

-- | Profunctors
--   
--   Profunctors
@package profunctors
@version 4.0.1

module Data.Profunctor.Trace

-- | Coend of Profunctor from Hask -> Hask.
data Trace f
Trace :: f a a -> Trace f

-- | 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

-- | 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 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
dimap :: Profunctor p => (a -> b) -> (c -> d) -> p b c -> p a d
lmap :: Profunctor p => (a -> b) -> p b c -> p a c
rmap :: Profunctor p => (b -> c) -> p a b -> p a c
(#.) :: Profunctor p => (b -> c) -> p a b -> p a c
(.#) :: Profunctor p => p b c -> (a -> b) -> p a c
instance Functor w => Profunctor (Cokleisli w)
instance Monad m => Profunctor (Kleisli m)
instance Profunctor (Tagged *)
instance Profunctor (->)

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

-- | 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 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
dimap :: Profunctor p => (a -> b) -> (c -> d) -> p b c -> p a d
lmap :: Profunctor p => (a -> b) -> p b c -> p a c
rmap :: Profunctor p => (b -> c) -> p a b -> p a c

-- | Generalizing upstar of a strong Functor
--   
--   Minimal complete definition: first' or second'
--   
--   Note: Every Functor in Haskell is strong.
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)

-- | The generalization of DownStar of a "costrong" Functor
--   
--   Minimal complete definition: left' or right'
--   
--   Note: We use traverse and extract as approximate
--   costrength as needed.
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)

-- | Lift a Functor into a Profunctor (forwards).
newtype UpStar f d c
UpStar :: (d -> f c) -> UpStar f d c
runUpStar :: UpStar f d c -> d -> f c

-- | Lift a Functor into a Profunctor (backwards).
newtype DownStar f d c
DownStar :: (f d -> c) -> DownStar f d c
runDownStar :: DownStar f d c -> f d -> c

-- | Wrap an arrow for use as a Profunctor.
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
instance Monoid r => Choice (Forget r)
instance ArrowChoice p => Choice (WrappedArrow p)
instance Choice (Tagged *)
instance Traversable w => Choice (DownStar w)
instance Comonad w => Choice (Cokleisli w)
instance Applicative f => Choice (UpStar f)
instance Monad m => Choice (Kleisli m)
instance Choice (->)
instance Strong (Forget r)
instance Arrow p => Strong (WrappedArrow p)
instance Functor m => Strong (UpStar m)
instance Monad m => Strong (Kleisli m)
instance Strong (->)
instance Traversable (Forget r a)
instance Foldable (Forget r a)
instance Functor (Forget r a)
instance Profunctor (Forget r)
instance Arrow p => Profunctor (WrappedArrow p)
instance ArrowLoop p => ArrowLoop (WrappedArrow p)
instance ArrowApply p => ArrowApply (WrappedArrow p)
instance ArrowChoice p => ArrowChoice (WrappedArrow p)
instance ArrowZero p => ArrowZero (WrappedArrow p)
instance Arrow p => Arrow (WrappedArrow p)
instance Category p => Category (WrappedArrow p)
instance Functor (DownStar f a)
instance Functor f => Profunctor (DownStar f)
instance Functor f => Functor (UpStar f a)
instance Functor f => Profunctor (UpStar f)

module Data.Profunctor.Rep

-- | A Profunctor p is Representable if there exists
--   a Functor f such that p d c is isomorphic to
--   d -> f c.
class (Functor (Rep p), Profunctor p) => Representable p where type family Rep p :: * -> *
tabulate :: Representable p => (d -> Rep p c) -> p d c
rep :: Representable p => p d c -> d -> Rep p c

-- | tabulate and rep form two halves of an isomorphism.
--   
--   This can be used with the combinators from the lens package.
--   
--   
--   tabulated :: Representable p => Iso' (d -> Rep p c) (p d c)
--   
tabulated :: (Representable p, Representable q) => Iso (d -> Rep p c) (d' -> Rep q c') (p d c) (q d' c')

-- | A Profunctor p is Corepresentable if there
--   exists a Functor f such that p d c is
--   isomorphic to f d -> c.
class (Functor (Corep p), Profunctor p) => Corepresentable p where type family Corep p :: * -> *
cotabulate :: Corepresentable p => (Corep p d -> c) -> p d c
corep :: Corepresentable p => p d c -> Corep p d -> c

-- | cotabulate and corep form two halves of an isomorphism.
--   
--   This can be used with the combinators from the lens package.
--   
--   
--   tabulated :: Corep f p => Iso' (f d -> c) (p d c)
--   
cotabulated :: (Corepresentable p, Corepresentable q) => Iso (Corep p d -> c) (Corep q d' -> c') (p d c) (q d' c')
instance Functor f => Corepresentable (DownStar f)
instance Corepresentable (Tagged *)
instance Functor w => Corepresentable (Cokleisli w)
instance Corepresentable (->)
instance Functor f => Representable (UpStar f)
instance (Monad m, Functor m) => Representable (Kleisli m)
instance Representable (->)

module Data.Profunctor.Composition

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

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

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

-- | Profunctor composition generalizes Functor composition
--   in two ways.
--   
--   This is the first, which shows that exists b. (a -> f b, b
--   -> g c) is isomorphic to a -> f (g c).
--   
--   
--   upstars :: Functor f => Iso' (Procompose (UpStar f) (UpStar g) d c) (UpStar (Compose f g) d c)
--   
upstars :: Functor f => Iso (Procompose (UpStar f) (UpStar g) d c) (Procompose (UpStar f') (UpStar g') d' c') (UpStar (Compose f g) d c) (UpStar (Compose f' g') d' c')

-- | This is a variant on upstars that uses Kleisli instead
--   of UpStar.
--   
--   
--   kleislis :: Monad f => Iso' (Procompose (Kleisli f) (Kleisli g) d c) (Kleisli (Compose f g) d c)
--   
kleislis :: Monad f => Iso (Procompose (Kleisli f) (Kleisli g) d c) (Procompose (Kleisli f') (Kleisli g') d' c') (Kleisli (Compose f g) d c) (Kleisli (Compose f' g') d' c')

-- | Profunctor composition generalizes Functor composition
--   in two ways.
--   
--   This is the second, which shows that exists b. (f a -> b, g b
--   -> c) is isomorphic to g (f a) -> c.
--   
--   
--   downstars :: Functor f => Iso' (Procompose (DownStar f) (DownStar g) d c) (DownStar (Compose g f) d c)
--   
downstars :: Functor g => Iso (Procompose (DownStar f) (DownStar g) d c) (Procompose (DownStar f') (DownStar g') d' c') (DownStar (Compose g f) d c) (DownStar (Compose g' f') d' c')

-- | This is a variant on downstars that uses Cokleisli
--   instead of DownStar.
--   
--   
--   cokleislis :: Functor f => Iso' (Procompose (Cokleisli f) (Cokleisli g) d c) (Cokleisli (Compose g f) d c)
--   
cokleislis :: Functor g => Iso (Procompose (Cokleisli f) (Cokleisli g) d c) (Procompose (Cokleisli f') (Cokleisli g') d' c') (Cokleisli (Compose g f) d c) (Cokleisli (Compose g' f') d' c')
instance (Choice p, Choice q) => Choice (Procompose p q)
instance (Strong p, Strong q) => Strong (Procompose p q)
instance (Corepresentable p, Corepresentable q) => Corepresentable (Procompose p q)
instance (Representable p, Representable q) => Representable (Procompose p q)
instance Profunctor q => Functor (Procompose p q a)
instance (Profunctor p, Profunctor q) => Profunctor (Procompose p q)

module Data.Profunctor.Rift

-- | This represents the right Kan lift of a Profunctor q
--   along a Profunctor p 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 x a -> q x b) -> Rift p q a b
runRift :: Rift p q a b -> forall x. p x a -> q x b

-- | The 2-morphism that defines a right Kan lift.
--   
--   Note: When f is left adjoint to Rift f
--   (->) then decomposeRift is the counit of the
--   adjunction.
decomposeRift :: Procompose q (Rift q p) a b -> p a b
precomposeRift :: Profunctor q => Procompose (Rift p (->)) q a b -> Rift p q a b
instance p ~ q => Category (Rift p q)
instance Profunctor q => Functor (Rift p q a)
instance (Profunctor p, Profunctor q) => Profunctor (Rift p q)

module Data.Profunctor.Collage

-- | The cograph of a Profunctor.
data Collage k b a
L :: (b -> b') -> Collage k (L b) (L b')
R :: (a -> a') -> Collage k (R a) (R a')
C :: k b a -> Collage k (L b) (R a)
instance Profunctor k => Ob (Collage k) (R a)
instance Profunctor k => Ob (Collage k) (L a)
instance Profunctor k => Semigroupoid (Collage k)
