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 ≡ idIf 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 gThese 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
Methods
dimap :: (a -> b) -> (c -> d) -> p b c -> p a dlmap :: (a -> b) -> p b c -> p a crmap :: (b -> c) -> p a b -> p a c(#.) :: Coercible c b => q b c -> p a b -> p a cinfixr 9Strictly 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
unsafeCoerceto implement this combinator and it has no way to validate that your function meets the requirements.If you implement this combinator with
unsafeCoerce, then you are taking upon yourself the obligation that you don't use GADT-like tricks to distinguish values.If you import Data.Profunctor.Unsafe you are taking upon yourself the obligation that you will only call this with a first argument that is operationally identity.
The semantics of this function with respect to bottoms should match the default definition:
(Profuctor.Unsafe.#.) ≡ \_ -> \p -> p `seq` rmap coerce p(.#) :: Coercible b a => p b c -> q a b -> p a cinfixl 8Strictly 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
unsafeCoerceto implement this combinator and it has no way to validate that your function meets the requirements.If you implement this combinator with
unsafeCoerce, then you are taking upon yourself the obligation that you don't use GADT-like tricks to distinguish values.If you import Data.Profunctor.Unsafe you are taking upon yourself the obligation that you will only call this with a second argument that is operationally identity.
(.#) ≡ \p -> p `seq` \f -> lmap coerce p
Instances38Profunctor, …
Monad m => Profunctor (Kleisli m)Defined in profunctors-5.6.3 · Data.Profunctor.UnsafeProfunctor TaggedDefined in profunctors-5.6.3 · Data.Profunctor.UnsafeProfunctor (CopastroSum p)Defined in profunctors-5.6.3 · Data.Profunctor.ChoiceProfunctor (CotambaraSum p)Defined in profunctors-5.6.3 · Data.Profunctor.ChoiceProfunctor (PastroSum p)Defined in profunctors-5.6.3 · Data.Profunctor.ChoiceProfunctor (Environment p)Defined in profunctors-5.6.3 · Data.Profunctor.ClosedProfunctor (FreeMapping p)Defined in profunctors-5.6.3 · Data.Profunctor.MappingProfunctor (Copastro p)Defined in profunctors-5.6.3 · Data.Profunctor.StrongProfunctor (Cotambara p)Defined in profunctors-5.6.3 · Data.Profunctor.StrongProfunctor (Pastro p)Defined in profunctors-5.6.3 · Data.Profunctor.StrongProfunctor (Baz t)Defined in profunctors-5.6.3 · Data.Profunctor.TraversingProfunctor (Bazaar a)Defined in profunctors-5.6.3 · Data.Profunctor.TraversingProfunctor (FreeTraversing p)Defined in profunctors-5.6.3 · Data.Profunctor.TraversingProfunctor (Coyoneda p)Defined in profunctors-5.6.3 · Data.Profunctor.YonedaProfunctor (Yoneda p)Defined in profunctors-5.6.3 · Data.Profunctor.YonedaProfunctor p => Profunctor (TambaraSum p)Defined in profunctors-5.6.3 · Data.Profunctor.ChoiceProfunctor p => Profunctor (Closure p)Defined in profunctors-5.6.3 · Data.Profunctor.ClosedProfunctor p => Profunctor (CofreeMapping p)Defined in profunctors-5.6.3 · Data.Profunctor.MappingProfunctor p => Profunctor (Tambara p)Defined in profunctors-5.6.3 · Data.Profunctor.StrongProfunctor p => Profunctor (CofreeTraversing p)Defined in profunctors-5.6.3 · Data.Profunctor.TraversingFunctor f => Profunctor (Costar f)Defined in profunctors-5.6.3 · Data.Profunctor.TypesFunctor f => Profunctor (Star f)Defined in profunctors-5.6.3 · Data.Profunctor.TypesFunctor w => Profunctor (Cokleisli w)Defined in profunctors-5.6.3 · Data.Profunctor.UnsafeProfunctor (->)Defined in profunctors-5.6.3 · Data.Profunctor.UnsafeProfunctor (Forget r)Defined in profunctors-5.6.3 · Data.Profunctor.TypesContravariant f => Profunctor (Clown f)Defined in profunctors-5.6.3 · Data.Profunctor.UnsafeFunctor f => Profunctor (Joker f)Defined in profunctors-5.6.3 · Data.Profunctor.UnsafeArrow p => Profunctor (WrappedArrow p)Defined in profunctors-5.6.3 · Data.Profunctor.TypesProfunctor p => Profunctor (WrappedProfunctor p)Defined in invariant-0.6.4 · Data.Functor.InvariantProfunctor p => Profunctor (Codensity p)Defined in profunctors-5.6.3 · Data.Profunctor.Ran(Profunctor p, Profunctor q) => Profunctor (Product p q)Defined in profunctors-5.6.3 · Data.Profunctor.Unsafe(Profunctor p, Profunctor q) => Profunctor (Sum p q)Defined in profunctors-5.6.3 · Data.Profunctor.Unsafe(Functor f, Profunctor p) => Profunctor (Tannen f p)Defined in profunctors-5.6.3 · Data.Profunctor.Unsafe(Functor f, Profunctor p) => Profunctor (Cayley f p)Defined in profunctors-5.6.3 · Data.Profunctor.Cayley(Profunctor p, Profunctor q) => Profunctor (Procompose p q)Defined in profunctors-5.6.3 · Data.Profunctor.Composition(Profunctor p, Profunctor q) => Profunctor (Rift p q)Defined in profunctors-5.6.3 · Data.Profunctor.Composition(Profunctor p, Profunctor q) => Profunctor (Ran p q)Defined in profunctors-5.6.3 · Data.Profunctor.Ran(Profunctor p, Functor f, Functor g) => Profunctor (Biff p f g)Defined in profunctors-5.6.3 · Data.Profunctor.Unsafe