Copyright | (C) 2011-2015 Edward Kmett |
---|---|
License | BSD-style (see the file LICENSE) |
Maintainer | Edward Kmett <ekmett@gmail.com> |
Stability | provisional |
Portability | portable |
Safe Haskell | Safe |
Language | Haskell2010 |
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/
- class Profunctor p where
- class Profunctor p => Strong p where
- uncurry' :: Strong p => p a (b -> c) -> p (a, b) c
- class Profunctor p => Choice p where
- class Profunctor p => Closed p where
- curry' :: Closed p => p (a, b) c -> p a (b -> c)
- class (Traversing p, Closed p) => Mapping p where
- class Profunctor p => Costrong p where
- class Profunctor p => Cochoice p where
- newtype Star f d c = Star {
- runStar :: d -> f c
- newtype Costar f d c = Costar {
- runCostar :: f d -> c
- newtype WrappedArrow p a b = WrapArrow {
- unwrapArrow :: p a b
- newtype Forget r a b = Forget {
- runForget :: a -> r
- type (:->) p q = forall a b. p a b -> q a b
Profunctors
class Profunctor p where #
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 ilmap
(f.
g) ≡lmap
g.
lmap
frmap
(f.
g) ≡rmap
f.
rmap
g
Profunctorial Strength
class Profunctor p => Strong p where #
Generalizing Star
of a strong Functor
Note: Every Functor
in Haskell is strong with respect to (,)
.
This describes profunctor strength with respect to the product structure of Hask.
http://www-kb.is.s.u-tokyo.ac.jp/~asada/papers/arrStrMnd.pdf
Strong (->) # | |
Monad m => Strong (Kleisli m) # | |
Strong (Forget r) # | |
Arrow p => Strong (WrappedArrow p) # | |
Functor m => Strong (Star m) # | |
Strong (Pastro p) # | |
Profunctor p => Strong (Tambara p) # | |
Strong p => Strong (Closure p) # | |
Strong (FreeTraversing p) # | |
Profunctor p => Strong (CofreeTraversing p) # | |
Strong (FreeMapping p) # | |
Profunctor p => Strong (CofreeMapping p) # | |
Strong p => Strong (Coyoneda p) # | |
Strong p => Strong (Yoneda p) # | |
(Functor f, Strong p) => Strong (Cayley f p) # | |
(Strong p, Strong q) => Strong (Procompose p q) # | |
Contravariant f => Strong (Clown * * f) # | |
(Strong p, Strong q) => Strong (Product * * p q) # | |
(Functor f, Strong p) => Strong (Tannen * * * f p) # | |
class Profunctor p => Choice p where #
The generalization of Costar
of Functor
that is strong with respect
to Either
.
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.
left' :: p a b -> p (Either a c) (Either b c) #
Laws:
left'
≡dimap
swapE swapE.
right'
where swapE ::Either
a b ->Either
b a swapE =either
Right
Left
rmap
Left
≡lmap
Left
.
left'
lmap
(right
f).
left'
≡rmap
(right
f).
left'
left'
.
left'
≡dimap
assocE unassocE.
left'
where assocE ::Either
(Either
a b) c ->Either
a (Either
b c) assocE (Left
(Left
a)) =Left
a assocE (Left
(Right
b)) =Right
(Left
b) assocE (Right
c) =Right
(Right
c) unassocE ::Either
a (Either
b c) ->Either
(Either
a b) c unassocE (Left
a) =Left
(Left
a) unassocE (Right
(Left
b) =Left
(Right
b) unassocE (Right
(Right
c)) =Right
c)
right' :: p a b -> p (Either c a) (Either c b) #
Laws:
right'
≡dimap
swapE swapE.
left'
where swapE ::Either
a b ->Either
b a swapE =either
Right
Left
rmap
Right
≡lmap
Right
.
right'
lmap
(left
f).
right'
≡rmap
(left
f).
right'
right'
.
right'
≡dimap
unassocE assocE.
right'
where assocE ::Either
(Either
a b) c ->Either
a (Either
b c) assocE (Left
(Left
a)) =Left
a assocE (Left
(Right
b)) =Right
(Left
b) assocE (Right
c) =Right
(Right
c) unassocE ::Either
a (Either
b c) ->Either
(Either
a b) c unassocE (Left
a) =Left
(Left
a) unassocE (Right
(Left
b) =Left
(Right
b) unassocE (Right
(Right
c)) =Right
c)
Choice (->) # | |
Monad m => Choice (Kleisli m) # | |
Comonad w => Choice (Cokleisli w) # |
|
Choice (Tagged *) # | |
Monoid r => Choice (Forget r) # | |
ArrowChoice p => Choice (WrappedArrow p) # | |
Traversable w => Choice (Costar w) # | |
Applicative f => Choice (Star f) # | |
Choice p => Choice (Tambara p) # | |
Choice (PastroSum p) # | |
Profunctor p => Choice (TambaraSum p) # | |
Choice (FreeTraversing p) # | |
Profunctor p => Choice (CofreeTraversing p) # | |
Choice (FreeMapping p) # | |
Profunctor p => Choice (CofreeMapping p) # | |
Choice p => Choice (Coyoneda p) # | |
Choice p => Choice (Yoneda p) # | |
(Functor f, Choice p) => Choice (Cayley f p) # | |
(Choice p, Choice q) => Choice (Procompose p q) # | |
Functor f => Choice (Joker * * f) # | |
(Choice p, Choice q) => Choice (Product * * p q) # | |
(Functor f, Choice p) => Choice (Tannen * * * f p) # | |
Closed
class Profunctor p => Closed p where #
A strong profunctor allows the monoidal structure to pass through.
A closed profunctor allows the closed structure to pass through.
Closed (->) # | |
(Distributive f, Monad f) => Closed (Kleisli f) # | |
Functor f => Closed (Cokleisli f) # | |
Closed (Tagged *) # | |
Functor f => Closed (Costar f) # | |
Distributive f => Closed (Star f) # | |
Closed (Environment p) # | |
Profunctor p => Closed (Closure p) # | |
Closed (FreeMapping p) # | |
Profunctor p => Closed (CofreeMapping p) # | |
Closed p => Closed (Coyoneda p) # | |
Closed p => Closed (Yoneda p) # | |
(Closed p, Closed q) => Closed (Procompose p q) # | |
(Closed p, Closed q) => Closed (Product * * p q) # | |
(Functor f, Closed p) => Closed (Tannen * * * f p) # | |
class (Traversing p, Closed p) => Mapping p where #
Mapping (->) # | |
(Monad m, Distributive m) => Mapping (Kleisli m) # | |
(Applicative m, Distributive m) => Mapping (Star m) # | |
Mapping (FreeMapping p) # | |
Profunctor p => Mapping (CofreeMapping p) # | |
Mapping p => Mapping (Coyoneda p) # | |
Mapping p => Mapping (Yoneda p) # | |
(Mapping p, Mapping q) => Mapping (Procompose p q) # | |
Profunctorial Costrength
class Profunctor p => Costrong p where #
Costrong (->) # | |
MonadFix m => Costrong (Kleisli m) # | |
Functor f => Costrong (Cokleisli f) # | |
Costrong (Tagged *) # | |
ArrowLoop p => Costrong (WrappedArrow p) # | |
Functor f => Costrong (Costar f) # | |
Costrong (Copastro p) # | |
Costrong (Cotambara p) # | |
Costrong p => Costrong (Coyoneda p) # | |
Costrong p => Costrong (Yoneda p) # | |
(Corepresentable p, Corepresentable q) => Costrong (Procompose p q) # | |
(Costrong p, Costrong q) => Costrong (Product * * p q) # | |
(Functor f, Costrong p) => Costrong (Tannen * * * f p) # | |
class Profunctor p => Cochoice p where #
unleft :: p (Either a d) (Either b d) -> p a b #
Laws:
unleft
≡unright
.
dimap
swapE swapE where swapE ::Either
a b ->Either
b a swapE =either
Right
Left
rmap
(either
id
absurd
) ≡unleft
.
lmap
(either
id
absurd
)unfirst
.
rmap
(second
f) ≡unfirst
.
lmap
(second
f)unleft
.
unleft
≡unleft
.
dimap
assocE unassocE where assocE ::Either
(Either
a b) c ->Either
a (Either
b c) assocE (Left
(Left
a)) =Left
a assocE (Left
(Right
b)) =Right
(Left
b) assocE (Right
c) =Right
(Right
c) unassocE ::Either
a (Either
b c) ->Either
(Either
a b) c unassocE (Left
a) =Left
(Left
a) unassocE (Right
(Left
b) =Left
(Right
b) unassocE (Right
(Right
c)) =Right
c)
unright :: p (Either d a) (Either d b) -> p a b #
Laws:
unright
≡unleft
.
dimap
swapE swapE where swapE ::Either
a b ->Either
b a swapE =either
Right
Left
rmap
(either
absurd
id
) ≡unright
.
lmap
(either
absurd
id
)unsecond
.
rmap
(first
f) ≡unsecond
.
lmap
(first
f)unright
.
unright
≡unright
.
dimap
unassocE assocE where assocE ::Either
(Either
a b) c ->Either
a (Either
b c) assocE (Left
(Left
a)) =Left
a assocE (Left
(Right
b)) =Right
(Left
b) assocE (Right
c) =Right
(Right
c) unassocE ::Either
a (Either
b c) ->Either
(Either
a b) c unassocE (Left
a) =Left
(Left
a) unassocE (Right
(Left
b) =Left
(Right
b) unassocE (Right
(Right
c)) =Right
c)
Cochoice (->) # | |
Applicative f => Cochoice (Costar f) # | |
Traversable f => Cochoice (Star f) # | |
Cochoice (CopastroSum p) # | |
Cochoice (CotambaraSum p) # | |
Cochoice p => Cochoice (Coyoneda p) # | |
Cochoice p => Cochoice (Yoneda p) # | |
(Cochoice p, Cochoice q) => Cochoice (Product * * p q) # | |
(Functor f, Cochoice p) => Cochoice (Tannen * * * f p) # | |
Common Profunctors
Lift a Functor
into a Profunctor
(forwards).
Functor f => Profunctor (Star f) # | |
Functor m => Strong (Star m) # | |
Traversable f => Cochoice (Star f) # | |
Applicative f => Choice (Star f) # | |
Distributive f => Closed (Star f) # | |
Applicative m => Traversing (Star m) # | |
(Applicative m, Distributive m) => Mapping (Star m) # | |
Functor f => Representable (Star f) # | |
Functor f => Sieve (Star f) f # | |
Monad f => Category * (Star f) # | |
Monad f => Monad (Star f a) # | |
Functor f => Functor (Star f a) # | |
Applicative f => Applicative (Star f a) # | |
Alternative f => Alternative (Star f a) # | |
MonadPlus f => MonadPlus (Star f a) # | |
Distributive f => Distributive (Star f a) # | |
type Rep (Star f) # | |
Lift a Functor
into a Profunctor
(backwards).
Functor f => Profunctor (Costar f) # | |
Functor f => Costrong (Costar f) # | |
Applicative f => Cochoice (Costar f) # | |
Traversable w => Choice (Costar w) # | |
Functor f => Closed (Costar f) # | |
Functor f => Corepresentable (Costar f) # | |
Functor f => Cosieve (Costar f) f # | |
Monad (Costar f a) # | |
Functor (Costar f a) # | |
Applicative (Costar f a) # | |
Distributive (Costar f d) # | |
type Corep (Costar f) # | |
newtype WrappedArrow p a b #
Wrap an arrow for use as a Profunctor
.
WrapArrow | |
|
Arrow p => Arrow (WrappedArrow p) # | |
ArrowZero p => ArrowZero (WrappedArrow p) # | |
ArrowChoice p => ArrowChoice (WrappedArrow p) # | |
ArrowApply p => ArrowApply (WrappedArrow p) # | |
ArrowLoop p => ArrowLoop (WrappedArrow p) # | |
Arrow p => Profunctor (WrappedArrow p) # | |
ArrowLoop p => Costrong (WrappedArrow p) # | |
Arrow p => Strong (WrappedArrow p) # | |
ArrowChoice p => Choice (WrappedArrow p) # | |
Category * p => Category * (WrappedArrow p) # | |