-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Haskell 98 Profunctors -- -- Haskell 98 Profunctors @package profunctors @version 3.3 -- | 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 idid
--   
-- -- If you supply lmap and rmap, ensure: -- --
--   lmap idid
--   rmap idid
--   
-- -- 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 idid
--   
-- -- If you supply lmap and rmap, ensure: -- --
--   lmap idid
--   rmap idid
--   
-- -- 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)