profunctors-5.2: Profunctors

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 | Trustworthy
Language | Haskell2010

Data.Profunctor.Unsafe

Contents

- Profunctors

Description

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

Synopsis

- class Profunctor p where

# 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 i
    lmap (f . g) ≡ lmap g . lmap f
    rmap (f . g) ≡ rmap f . rmap g

Minimal complete definition

dimap | lmap, rmap

Methods

dimap :: (a -> b) -> (c -> d) -> p b c -> p a d #

Map over both arguments at the same time.

    dimap f g ≡ lmap f . rmap g

lmap :: (a -> b) -> p b c -> p a c #

Map the first argument contravariantly.

    lmap f ≡ dimap f id

rmap :: (b -> c) -> p a b -> p a c #

Map the second argument covariantly.

    rmap ≡ dimap id

(#.) :: Coercible c b => (b -> c) -> p a b -> p a c infixr 9 #

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:

    (#.) ≡ \f -> \p -> p `seq` rmap f p

(.#) :: Coercible b a => p b c -> (a -> b) -> p a c infixl 8 #

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

Instances

Profunctor (->) # |
Methods dimap :: (a -> b) -> (c -> d) -> (b -> c) -> a -> d # lmap :: (a -> b) -> (b -> c) -> a -> c # rmap :: (b -> c) -> (a -> b) -> a -> c # (#.) :: Coercible * c b => (b -> c) -> (a -> b) -> a -> c # (.#) :: Coercible * b a => (b -> c) -> (a -> b) -> a -> c #
Monad m => Profunctor (Kleisli m) # |
Methods dimap :: (a -> b) -> (c -> d) -> Kleisli m b c -> Kleisli m a d # lmap :: (a -> b) -> Kleisli m b c -> Kleisli m a c # rmap :: (b -> c) -> Kleisli m a b -> Kleisli m a c # (#.) :: Coercible * c b => (b -> c) -> Kleisli m a b -> Kleisli m a c # (.#) :: Coercible * b a => Kleisli m b c -> (a -> b) -> Kleisli m a c #
Functor w => Profunctor (Cokleisli w) # |
Methods dimap :: (a -> b) -> (c -> d) -> Cokleisli w b c -> Cokleisli w a d # lmap :: (a -> b) -> Cokleisli w b c -> Cokleisli w a c # rmap :: (b -> c) -> Cokleisli w a b -> Cokleisli w a c # (#.) :: Coercible * c b => (b -> c) -> Cokleisli w a b -> Cokleisli w a c # (.#) :: Coercible * b a => Cokleisli w b c -> (a -> b) -> Cokleisli w a c #
Profunctor (Tagged *) # |
Methods dimap :: (a -> b) -> (c -> d) -> Tagged * b c -> Tagged * a d # lmap :: (a -> b) -> Tagged * b c -> Tagged * a c # rmap :: (b -> c) -> Tagged * a b -> Tagged * a c # (#.) :: Coercible * c b => (b -> c) -> Tagged * a b -> Tagged * a c # (.#) :: Coercible * b a => Tagged * b c -> (a -> b) -> Tagged * a c #
Profunctor (Forget r) # |
Methods dimap :: (a -> b) -> (c -> d) -> Forget r b c -> Forget r a d # lmap :: (a -> b) -> Forget r b c -> Forget r a c # rmap :: (b -> c) -> Forget r a b -> Forget r a c # (#.) :: Coercible * c b => (b -> c) -> Forget r a b -> Forget r a c # (.#) :: Coercible * b a => Forget r b c -> (a -> b) -> Forget r a c #
Arrow p => Profunctor (WrappedArrow p) # |
Methods dimap :: (a -> b) -> (c -> d) -> WrappedArrow p b c -> WrappedArrow p a d # lmap :: (a -> b) -> WrappedArrow p b c -> WrappedArrow p a c # rmap :: (b -> c) -> WrappedArrow p a b -> WrappedArrow p a c # (#.) :: Coercible * c b => (b -> c) -> WrappedArrow p a b -> WrappedArrow p a c # (.#) :: Coercible * b a => WrappedArrow p b c -> (a -> b) -> WrappedArrow p a c #
Functor f => Profunctor (Costar f) # |
Methods dimap :: (a -> b) -> (c -> d) -> Costar f b c -> Costar f a d # lmap :: (a -> b) -> Costar f b c -> Costar f a c # rmap :: (b -> c) -> Costar f a b -> Costar f a c # (#.) :: Coercible * c b => (b -> c) -> Costar f a b -> Costar f a c # (.#) :: Coercible * b a => Costar f b c -> (a -> b) -> Costar f a c #
Functor f => Profunctor (Star f) # |
Methods dimap :: (a -> b) -> (c -> d) -> Star f b c -> Star f a d # lmap :: (a -> b) -> Star f b c -> Star f a c # rmap :: (b -> c) -> Star f a b -> Star f a c # (#.) :: Coercible * c b => (b -> c) -> Star f a b -> Star f a c # (.#) :: Coercible * b a => Star f b c -> (a -> b) -> Star f a c #
Profunctor (Copastro p) # |
Methods dimap :: (a -> b) -> (c -> d) -> Copastro p b c -> Copastro p a d # lmap :: (a -> b) -> Copastro p b c -> Copastro p a c # rmap :: (b -> c) -> Copastro p a b -> Copastro p a c # (#.) :: Coercible * c b => (b -> c) -> Copastro p a b -> Copastro p a c # (.#) :: Coercible * b a => Copastro p b c -> (a -> b) -> Copastro p a c #
Profunctor (Cotambara p) # |
Methods dimap :: (a -> b) -> (c -> d) -> Cotambara p b c -> Cotambara p a d # lmap :: (a -> b) -> Cotambara p b c -> Cotambara p a c # rmap :: (b -> c) -> Cotambara p a b -> Cotambara p a c # (#.) :: Coercible * c b => (b -> c) -> Cotambara p a b -> Cotambara p a c # (.#) :: Coercible * b a => Cotambara p b c -> (a -> b) -> Cotambara p a c #
Profunctor (Pastro p) # |
Methods dimap :: (a -> b) -> (c -> d) -> Pastro p b c -> Pastro p a d # lmap :: (a -> b) -> Pastro p b c -> Pastro p a c # rmap :: (b -> c) -> Pastro p a b -> Pastro p a c # (#.) :: Coercible * c b => (b -> c) -> Pastro p a b -> Pastro p a c # (.#) :: Coercible * b a => Pastro p b c -> (a -> b) -> Pastro p a c #
Profunctor p => Profunctor (Tambara p) # |
Methods dimap :: (a -> b) -> (c -> d) -> Tambara p b c -> Tambara p a d # lmap :: (a -> b) -> Tambara p b c -> Tambara p a c # rmap :: (b -> c) -> Tambara p a b -> Tambara p a c # (#.) :: Coercible * c b => (b -> c) -> Tambara p a b -> Tambara p a c # (.#) :: Coercible * b a => Tambara p b c -> (a -> b) -> Tambara p a c #
Profunctor (Environment p) # |
Methods dimap :: (a -> b) -> (c -> d) -> Environment p b c -> Environment p a d # lmap :: (a -> b) -> Environment p b c -> Environment p a c # rmap :: (b -> c) -> Environment p a b -> Environment p a c # (#.) :: Coercible * c b => (b -> c) -> Environment p a b -> Environment p a c # (.#) :: Coercible * b a => Environment p b c -> (a -> b) -> Environment p a c #
Profunctor p => Profunctor (Closure p) # |
Methods dimap :: (a -> b) -> (c -> d) -> Closure p b c -> Closure p a d # lmap :: (a -> b) -> Closure p b c -> Closure p a c # rmap :: (b -> c) -> Closure p a b -> Closure p a c # (#.) :: Coercible * c b => (b -> c) -> Closure p a b -> Closure p a c # (.#) :: Coercible * b a => Closure p b c -> (a -> b) -> Closure p a c #
Profunctor (CopastroSum p) # |
Methods dimap :: (a -> b) -> (c -> d) -> CopastroSum p b c -> CopastroSum p a d # lmap :: (a -> b) -> CopastroSum p b c -> CopastroSum p a c # rmap :: (b -> c) -> CopastroSum p a b -> CopastroSum p a c # (#.) :: Coercible * c b => (b -> c) -> CopastroSum p a b -> CopastroSum p a c # (.#) :: Coercible * b a => CopastroSum p b c -> (a -> b) -> CopastroSum p a c #
Profunctor (CotambaraSum p) # |
Methods dimap :: (a -> b) -> (c -> d) -> CotambaraSum p b c -> CotambaraSum p a d # lmap :: (a -> b) -> CotambaraSum p b c -> CotambaraSum p a c # rmap :: (b -> c) -> CotambaraSum p a b -> CotambaraSum p a c # (#.) :: Coercible * c b => (b -> c) -> CotambaraSum p a b -> CotambaraSum p a c # (.#) :: Coercible * b a => CotambaraSum p b c -> (a -> b) -> CotambaraSum p a c #
Profunctor (PastroSum p) # |
Methods dimap :: (a -> b) -> (c -> d) -> PastroSum p b c -> PastroSum p a d # lmap :: (a -> b) -> PastroSum p b c -> PastroSum p a c # rmap :: (b -> c) -> PastroSum p a b -> PastroSum p a c # (#.) :: Coercible * c b => (b -> c) -> PastroSum p a b -> PastroSum p a c # (.#) :: Coercible * b a => PastroSum p b c -> (a -> b) -> PastroSum p a c #
Profunctor p => Profunctor (TambaraSum p) # |
Methods dimap :: (a -> b) -> (c -> d) -> TambaraSum p b c -> TambaraSum p a d # lmap :: (a -> b) -> TambaraSum p b c -> TambaraSum p a c # rmap :: (b -> c) -> TambaraSum p a b -> TambaraSum p a c # (#.) :: Coercible * c b => (b -> c) -> TambaraSum p a b -> TambaraSum p a c # (.#) :: Coercible * b a => TambaraSum p b c -> (a -> b) -> TambaraSum p a c #
Profunctor (FreeTraversing p) # |
Methods dimap :: (a -> b) -> (c -> d) -> FreeTraversing p b c -> FreeTraversing p a d # lmap :: (a -> b) -> FreeTraversing p b c -> FreeTraversing p a c # rmap :: (b -> c) -> FreeTraversing p a b -> FreeTraversing p a c # (#.) :: Coercible * c b => (b -> c) -> FreeTraversing p a b -> FreeTraversing p a c # (.#) :: Coercible * b a => FreeTraversing p b c -> (a -> b) -> FreeTraversing p a c #
Profunctor p => Profunctor (CofreeTraversing p) # |
Methods dimap :: (a -> b) -> (c -> d) -> CofreeTraversing p b c -> CofreeTraversing p a d # lmap :: (a -> b) -> CofreeTraversing p b c -> CofreeTraversing p a c # rmap :: (b -> c) -> CofreeTraversing p a b -> CofreeTraversing p a c # (#.) :: Coercible * c b => (b -> c) -> CofreeTraversing p a b -> CofreeTraversing p a c # (.#) :: Coercible * b a => CofreeTraversing p b c -> (a -> b) -> CofreeTraversing p a c #
Profunctor (FreeMapping p) # |
Methods dimap :: (a -> b) -> (c -> d) -> FreeMapping p b c -> FreeMapping p a d # lmap :: (a -> b) -> FreeMapping p b c -> FreeMapping p a c # rmap :: (b -> c) -> FreeMapping p a b -> FreeMapping p a c # (#.) :: Coercible * c b => (b -> c) -> FreeMapping p a b -> FreeMapping p a c # (.#) :: Coercible * b a => FreeMapping p b c -> (a -> b) -> FreeMapping p a c #
Profunctor p => Profunctor (CofreeMapping p) # |
Methods dimap :: (a -> b) -> (c -> d) -> CofreeMapping p b c -> CofreeMapping p a d # lmap :: (a -> b) -> CofreeMapping p b c -> CofreeMapping p a c # rmap :: (b -> c) -> CofreeMapping p a b -> CofreeMapping p a c # (#.) :: Coercible * c b => (b -> c) -> CofreeMapping p a b -> CofreeMapping p a c # (.#) :: Coercible * b a => CofreeMapping p b c -> (a -> b) -> CofreeMapping p a c #
Profunctor p => Profunctor (Codensity p) # |
Methods dimap :: (a -> b) -> (c -> d) -> Codensity p b c -> Codensity p a d # lmap :: (a -> b) -> Codensity p b c -> Codensity p a c # rmap :: (b -> c) -> Codensity p a b -> Codensity p a c # (#.) :: Coercible * c b => (b -> c) -> Codensity p a b -> Codensity p a c # (.#) :: Coercible * b a => Codensity p b c -> (a -> b) -> Codensity p a c #
(Functor f, Profunctor p) => Profunctor (Cayley f p) # |
Methods dimap :: (a -> b) -> (c -> d) -> Cayley f p b c -> Cayley f p a d # lmap :: (a -> b) -> Cayley f p b c -> Cayley f p a c # rmap :: (b -> c) -> Cayley f p a b -> Cayley f p a c # (#.) :: Coercible * c b => (b -> c) -> Cayley f p a b -> Cayley f p a c # (.#) :: Coercible * b a => Cayley f p b c -> (a -> b) -> Cayley f p a c #
(Profunctor p, Profunctor q) => Profunctor (Rift p q) # |
Methods dimap :: (a -> b) -> (c -> d) -> Rift p q b c -> Rift p q a d # lmap :: (a -> b) -> Rift p q b c -> Rift p q a c # rmap :: (b -> c) -> Rift p q a b -> Rift p q a c # (#.) :: Coercible * c b => (b -> c) -> Rift p q a b -> Rift p q a c # (.#) :: Coercible * b a => Rift p q b c -> (a -> b) -> Rift p q a c #
(Profunctor p, Profunctor q) => Profunctor (Procompose p q) # |
Methods dimap :: (a -> b) -> (c -> d) -> Procompose p q b c -> Procompose p q a d # lmap :: (a -> b) -> Procompose p q b c -> Procompose p q a c # rmap :: (b -> c) -> Procompose p q a b -> Procompose p q a c # (#.) :: Coercible * c b => (b -> c) -> Procompose p q a b -> Procompose p q a c # (.#) :: Coercible * b a => Procompose p q b c -> (a -> b) -> Procompose p q a c #
(Profunctor p, Profunctor q) => Profunctor (Ran p q) # |
Methods dimap :: (a -> b) -> (c -> d) -> Ran p q b c -> Ran p q a d # lmap :: (a -> b) -> Ran p q b c -> Ran p q a c # rmap :: (b -> c) -> Ran p q a b -> Ran p q a c # (#.) :: Coercible * c b => (b -> c) -> Ran p q a b -> Ran p q a c # (.#) :: Coercible * b a => Ran p q b c -> (a -> b) -> Ran p q a c #
Functor f => Profunctor (Joker * * f) # |
Methods dimap :: (a -> b) -> (c -> d) -> Joker * * f b c -> Joker * * f a d # lmap :: (a -> b) -> Joker * * f b c -> Joker * * f a c # rmap :: (b -> c) -> Joker * * f a b -> Joker * * f a c # (#.) :: Coercible * c b => (b -> c) -> Joker * * f a b -> Joker * * f a c # (.#) :: Coercible * b a => Joker * * f b c -> (a -> b) -> Joker * * f a c #
Contravariant f => Profunctor (Clown * * f) # |
Methods dimap :: (a -> b) -> (c -> d) -> Clown * * f b c -> Clown * * f a d # lmap :: (a -> b) -> Clown * * f b c -> Clown * * f a c # rmap :: (b -> c) -> Clown * * f a b -> Clown * * f a c # (#.) :: Coercible * c b => (b -> c) -> Clown * * f a b -> Clown * * f a c # (.#) :: Coercible * b a => Clown * * f b c -> (a -> b) -> Clown * * f a c #
(Profunctor p, Profunctor q) => Profunctor (Product * * p q) # |
Methods dimap :: (a -> b) -> (c -> d) -> Product * * p q b c -> Product * * p q a d # lmap :: (a -> b) -> Product * * p q b c -> Product * * p q a c # rmap :: (b -> c) -> Product * * p q a b -> Product * * p q a c # (#.) :: Coercible * c b => (b -> c) -> Product * * p q a b -> Product * * p q a c # (.#) :: Coercible * b a => Product * * p q b c -> (a -> b) -> Product * * p q a c #
(Functor f, Profunctor p) => Profunctor (Tannen * * * f p) # |
Methods dimap :: (a -> b) -> (c -> d) -> Tannen * * * f p b c -> Tannen * * * f p a d # lmap :: (a -> b) -> Tannen * * * f p b c -> Tannen * * * f p a c # rmap :: (b -> c) -> Tannen * * * f p a b -> Tannen * * * f p a c # (#.) :: Coercible * c b => (b -> c) -> Tannen * * * f p a b -> Tannen * * * f p a c # (.#) :: Coercible * b a => Tannen * * * f p b c -> (a -> b) -> Tannen * * * f p a c #
(Profunctor p, Functor f, Functor g) => Profunctor (Biff * * * * p f g) # |
Methods dimap :: (a -> b) -> (c -> d) -> Biff * * * * p f g b c -> Biff * * * * p f g a d # lmap :: (a -> b) -> Biff * * * * p f g b c -> Biff * * * * p f g a c # rmap :: (b -> c) -> Biff * * * * p f g a b -> Biff * * * * p f g a c # (#.) :: Coercible * c b => (b -> c) -> Biff * * * * p f g a b -> Biff * * * * p f g a c # (.#) :: Coercible * b a => Biff * * * * p f g b c -> (a -> b) -> Biff * * * * p f g a c #