packages feed

profunctors 5.1.2 → 5.2

raw patch · 22 files changed

+1483/−774 lines, 22 filesdep +base-orphansdep ~basedep ~bifunctorsdep ~comonad

Dependencies added: base-orphans

Dependency ranges changed: base, bifunctors, comonad, transformers

Files

.travis.yml view
@@ -2,21 +2,16 @@  # See also https://github.com/hvr/multi-ghc-travis for more information env:- - GHCVER=7.0.1 CABALVER=1.16- - GHCVER=7.0.4 CABALVER=1.16- - GHCVER=7.2.2 CABALVER=1.16  - GHCVER=7.4.2 CABALVER=1.16  - GHCVER=7.6.3 CABALVER=1.16  - GHCVER=7.8.4 CABALVER=1.18  - GHCVER=7.10.1 CABALVER=1.22- - GHCVER=head CABALVER=1.22+ - GHCVER=8.0.1 CABALVER=1.24+ - GHCVER=head CABALVER=1.24  matrix:   allow_failures:-   - env: GHCVER=7.0.1 CABALVER=1.16-   - env: GHCVER=7.0.4 CABALVER=1.16-   - env: GHCVER=7.2.2 CABALVER=1.16-   - env: GHCVER=head CABALVER=1.22+   - env: GHCVER=head CABALVER=1.24  # Note: the distinction between `before_install` and `install` is not #       important.
CHANGELOG.markdown view
@@ -1,3 +1,9 @@+5.2+---+* Renamed `Cotambara` to `TambaraChoice` and `Pastro` to `PastroChoice`.+* Added a true `Cotambara` and `Copastro` construction for (co)freely generating costrength, along with `CotambaraSum` and `CopastroSum` variants.+* Engaged in a fair bit of bikeshedding about the module structure for lesser used modules in this package.+ 5.1.2 ----- * Added `Prep` and `Coprep` along with witnesses to the adjunctions `Prep -| Star : [Hask,Hask] -> Prof` and `Coprep -| Costar : [Hask,Hask]^op -> Prof`.
LICENSE view
@@ -1,4 +1,4 @@-Copyright 2011-2013 Edward Kmett+Copyright 2011-2015 Edward Kmett  All rights reserved. 
profunctors.cabal view
@@ -1,6 +1,6 @@ name:          profunctors category:      Control, Categories-version:       5.1.2+version:       5.2 license:       BSD3 cabal-version: >= 1.10 license-file:  LICENSE@@ -30,27 +30,29 @@ library   build-depends:     base                >= 4     && < 5,-    bifunctors          >= 5     && < 6,-    comonad             >= 4     && < 5,+    base-orphans        >= 0.4   && < 0.6,+    bifunctors          >= 5.2   && < 6,+    comonad             >= 4     && < 6,     contravariant       >= 1     && < 2,     distributive        >= 0.4.4 && < 1,     tagged              >= 0.4.4 && < 1,-    transformers        >= 0.2   && < 0.5+    transformers        >= 0.2   && < 0.6    exposed-modules:     Data.Profunctor     Data.Profunctor.Adjunction     Data.Profunctor.Cayley+    Data.Profunctor.Choice     Data.Profunctor.Closed-    Data.Profunctor.Codensity     Data.Profunctor.Composition+    Data.Profunctor.Mapping     Data.Profunctor.Monad-    Data.Profunctor.Monoid     Data.Profunctor.Ran     Data.Profunctor.Rep     Data.Profunctor.Sieve-    Data.Profunctor.Tambara-    Data.Profunctor.Trace+    Data.Profunctor.Strong+    Data.Profunctor.Traversing+    Data.Profunctor.Types     Data.Profunctor.Unsafe    ghc-options:     -Wall -O2
src/Data/Profunctor.hs view
@@ -7,7 +7,7 @@ #endif ----------------------------------------------------------------------------- -- |--- Copyright   :  (C) 2011-2013 Edward Kmett,+-- Copyright   :  (C) 2011-2015 Edward Kmett, -- License     :  BSD-style (see the file LICENSE) -- -- Maintainer  :  Edward Kmett <ekmett@gmail.com>@@ -28,7 +28,12 @@     Profunctor(dimap,lmap,rmap)   -- ** Profunctorial Strength   , Strong(..)+  , uncurry'   , Choice(..)+  -- ** Closed+  , Closed(..)+  , curry'+  , Mapping(..)   -- ** Profunctorial Costrength   , Costrong(..)   , Cochoice(..)@@ -42,396 +47,8 @@ #endif   ) where -import Control.Applicative hiding (WrappedArrow(..))-import Control.Arrow-import Control.Category-import Control.Comonad-import Control.Monad (liftM, MonadPlus(..))-import Control.Monad.Fix-import Data.Distributive-import Data.Foldable-import Data.Monoid-import Data.Tagged-import Data.Traversable-import Data.Tuple-import Data.Profunctor.Unsafe-import Prelude hiding (id,(.),sequence)--#if __GLASGOW_HASKELL__ >= 708-import Data.Coerce-#else-import Unsafe.Coerce-#endif--infixr 0 :->-type p :-> q = forall a b. p a b -> q a b----------------------------------------------------------------------------------- Star----------------------------------------------------------------------------------- | Lift a 'Functor' into a 'Profunctor' (forwards).-newtype Star f d c = Star { runStar :: d -> f c }--instance Functor f => Profunctor (Star f) where-  dimap ab cd (Star bfc) = Star (fmap cd . bfc . ab)-  {-# INLINE dimap #-}-  lmap k (Star f) = Star (f . k)-  {-# INLINE lmap #-}-  rmap k (Star f) = Star (fmap k . f)-  {-# INLINE rmap #-}-  -- We cannot safely overload ( #. ) because we didn't write the 'Functor'.-#if __GLASGOW_HASKELL__ >= 708-  p .# _ = coerce p-#else-  p .# _ = unsafeCoerce p-#endif-  {-# INLINE ( .# ) #-}--instance Functor f => Functor (Star f a) where-  fmap = rmap-  {-# INLINE fmap #-}--instance Applicative f => Applicative (Star f a) where-  pure a = Star $ \_ -> pure a-  Star ff <*> Star fx = Star $ \a -> ff a <*> fx a-  Star ff  *> Star fx = Star $ \a -> ff a  *> fx a-  Star ff <*  Star fx = Star $ \a -> ff a <*  fx a--instance Alternative f => Alternative (Star f a) where-  empty = Star $ \_ -> empty-  Star f <|> Star g = Star $ \a -> f a <|> g a--instance Monad f => Monad (Star f a) where-#if __GLASGOW_HASKELL__ < 710-  return a = Star $ \_ -> return a-#endif-  Star m >>= f = Star $ \ e -> do-    a <- m e-    runStar (f a) e--instance MonadPlus f => MonadPlus (Star f a) where-  mzero = Star $ \_ -> mzero-  Star f `mplus` Star g = Star $ \a -> f a `mplus` g a--instance Distributive f => Distributive (Star f a) where-  distribute fs = Star $ \a -> collect (($ a) .# runStar) fs----------------------------------------------------------------------------------- Costar----------------------------------------------------------------------------------- | Lift a 'Functor' into a 'Profunctor' (backwards).-newtype Costar f d c = Costar { runCostar :: f d -> c }--instance Functor f => Profunctor (Costar f) where-  dimap ab cd (Costar fbc) = Costar (cd . fbc . fmap ab)-  {-# INLINE dimap #-}-  lmap k (Costar f) = Costar (f . fmap k)-  {-# INLINE lmap #-}-  rmap k (Costar f) = Costar (k . f)-  {-# INLINE rmap #-}-#if __GLASGOW_HASKELL__ >= 708-  ( #. ) _ = coerce (\x -> x :: b) :: forall a b. Coercible b a => a -> b-#else-  ( #. ) _ = unsafeCoerce-#endif-  {-# INLINE ( #. ) #-}-  -- We cannot overload ( .# ) because we didn't write the 'Functor'.--instance Distributive (Costar f d) where-  distribute fs = Costar $ \gd -> fmap (($ gd) .# runCostar) fs--instance Functor (Costar f a) where-  fmap k (Costar f) = Costar (k . f)-  {-# INLINE fmap #-}-  a <$ _ = Costar $ \_ -> a-  {-# INLINE (<$) #-}--instance Applicative (Costar f a) where-  pure a = Costar $ \_ -> a-  Costar ff <*> Costar fx = Costar $ \a -> ff a (fx a)-  _ *> m = m-  m <* _ = m--instance Monad (Costar f a) where-  return = pure-  Costar m >>= f = Costar $ \ x -> runCostar (f (m x)) x----------------------------------------------------------------------------------- Wrapped Profunctors----------------------------------------------------------------------------------- | Wrap an arrow for use as a 'Profunctor'.-newtype WrappedArrow p a b = WrapArrow { unwrapArrow :: p a b }--instance Category p => Category (WrappedArrow p) where-  WrapArrow f . WrapArrow g = WrapArrow (f . g)-  {-# INLINE (.) #-}-  id = WrapArrow id-  {-# INLINE id #-}--instance Arrow p => Arrow (WrappedArrow p) where-  arr = WrapArrow . arr-  {-# INLINE arr #-}-  first = WrapArrow . first . unwrapArrow-  {-# INLINE first #-}-  second = WrapArrow . second . unwrapArrow-  {-# INLINE second #-}-  WrapArrow a *** WrapArrow b = WrapArrow (a *** b)-  {-# INLINE (***) #-}-  WrapArrow a &&& WrapArrow b = WrapArrow (a &&& b)-  {-# INLINE (&&&) #-}--instance ArrowZero p => ArrowZero (WrappedArrow p) where-  zeroArrow = WrapArrow zeroArrow-  {-# INLINE zeroArrow #-}--instance ArrowChoice p => ArrowChoice (WrappedArrow p) where-  left = WrapArrow . left . unwrapArrow-  {-# INLINE left #-}-  right = WrapArrow . right . unwrapArrow-  {-# INLINE right #-}-  WrapArrow a +++ WrapArrow b = WrapArrow (a +++ b)-  {-# INLINE (+++) #-}-  WrapArrow a ||| WrapArrow b = WrapArrow (a ||| b)-  {-# INLINE (|||) #-}--instance ArrowApply p => ArrowApply (WrappedArrow p) where-  app = WrapArrow $ app . arr (first unwrapArrow)-  {-# INLINE app #-}--instance ArrowLoop p => ArrowLoop (WrappedArrow p) where-  loop = WrapArrow . loop . unwrapArrow-  {-# INLINE loop #-}--instance Arrow p => Profunctor (WrappedArrow p) where-  lmap = (^>>)-  {-# INLINE lmap #-}-  rmap = (^<<)-  {-# INLINE rmap #-}-  -- We cannot safely overload ( #. ) or ( .# ) because we didn't write the 'Arrow'.----------------------------------------------------------------------------------- Forget---------------------------------------------------------------------------------newtype Forget r a b = Forget { runForget :: a -> r }--instance Profunctor (Forget r) where-  dimap f _ (Forget k) = Forget (k . f)-  {-# INLINE dimap #-}-  lmap f (Forget k) = Forget (k . f)-  {-# INLINE lmap #-}-  rmap _ (Forget k) = Forget k-  {-# INLINE rmap #-}--instance Functor (Forget r a) where-  fmap _ (Forget k) = Forget k-  {-# INLINE fmap #-}--instance Foldable (Forget r a) where-  foldMap _ _ = mempty-  {-# INLINE foldMap #-}--instance Traversable (Forget r a) where-  traverse _ (Forget k) = pure (Forget k)-  {-# INLINE traverse #-}----------------------------------------------------------------------------------- Strong----------------------------------------------------------------------------------- | 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>-class Profunctor p => Strong p where-  first' :: p a b  -> p (a, c) (b, c)-  first' = dimap swap swap . second'--  second' :: p a b -> p (c, a) (c, b)-  second' = dimap swap swap . first'---#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 708-  {-# MINIMAL first' | second' #-}-#endif--instance Strong (->) where-  first' ab ~(a, c) = (ab a, c)-  {-# INLINE first' #-}-  second' ab ~(c, a) = (c, ab a)--instance Monad m => Strong (Kleisli m) where-  first' (Kleisli f) = Kleisli $ \ ~(a, c) -> do-     b <- f a-     return (b, c)-  {-# INLINE first' #-}-  second' (Kleisli f) = Kleisli $ \ ~(c, a) -> do-     b <- f a-     return (c, b)-  {-# INLINE second' #-}--instance Functor m => Strong (Star m) where-  first' (Star f) = Star $ \ ~(a, c) -> (\b' -> (b', c)) <$> f a-  {-# INLINE first' #-}-  second' (Star f) = Star $ \ ~(c, a) -> (,) c <$> f a-  {-# INLINE second' #-}---- | 'Arrow' is 'Strong' 'Category'-instance Arrow p => Strong (WrappedArrow p) where-  first' (WrapArrow k) = WrapArrow (first k)-  {-# INLINE first' #-}-  second' (WrapArrow k) = WrapArrow (second k)-  {-# INLINE second' #-}--instance Strong (Forget r) where-  first' (Forget k) = Forget (k . fst)-  {-# INLINE first' #-}-  second' (Forget k) = Forget (k . snd)-  {-# INLINE second' #-}----------------------------------------------------------------------------------- Choice----------------------------------------------------------------------------------- | 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.-class Profunctor p => Choice p where-  left'  :: p a b -> p (Either a c) (Either b c)-  left' =  dimap (either Right Left) (either Right Left) . right'--  right' :: p a b -> p (Either c a) (Either c b)-  right' =  dimap (either Right Left) (either Right Left) . left'--#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 708-  {-# MINIMAL left' | right' #-}-#endif--instance Choice (->) where-  left' ab (Left a) = Left (ab a)-  left' _ (Right c) = Right c-  {-# INLINE left' #-}-  right' = fmap-  {-# INLINE right' #-}--instance Monad m => Choice (Kleisli m) where-  left' = left-  {-# INLINE left' #-}-  right' = right-  {-# INLINE right' #-}--instance Applicative f => Choice (Star f) where-  left' (Star f) = Star $ either (fmap Left . f) (pure . Right)-  {-# INLINE left' #-}-  right' (Star f) = Star $ either (pure . Left) (fmap Right . f)-  {-# INLINE right' #-}---- | 'extract' approximates 'costrength'-instance Comonad w => Choice (Cokleisli w) where-  left' = left-  {-# INLINE left' #-}-  right' = right-  {-# INLINE right' #-}---- NB: This instance is highly questionable-instance Traversable w => Choice (Costar w) where-  left' (Costar wab) = Costar (either Right Left . fmap wab . traverse (either Right Left))-  {-# INLINE left' #-}-  right' (Costar wab) = Costar (fmap wab . sequence)-  {-# INLINE right' #-}--instance Choice Tagged where-  left' (Tagged b) = Tagged (Left b)-  {-# INLINE left' #-}-  right' (Tagged b) = Tagged (Right b)-  {-# INLINE right' #-}--instance ArrowChoice p => Choice (WrappedArrow p) where-  left' (WrapArrow k) = WrapArrow (left k)-  {-# INLINE left' #-}-  right' (WrapArrow k) = WrapArrow (right k)-  {-# INLINE right' #-}--instance Monoid r => Choice (Forget r) where-  left' (Forget k) = Forget (either k (const mempty))-  {-# INLINE left' #-}-  right' (Forget k) = Forget (either (const mempty) k)-  {-# INLINE right' #-}------------------------------------------------------------------------------------- * Costrength for (,)------------------------------------------------------------------------------------- | Analogous to 'ArrowLoop', 'loop' = 'unfirst'-class Profunctor p => Costrong p where-  unfirst  :: p (a, d) (b, d) -> p a b-  unfirst = unsecond . dimap swap swap--  unsecond :: p (d, a) (d, b) -> p a b-  unsecond = unfirst . dimap swap swap--#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 708-  {-# MINIMAL unfirst | unsecond #-}-#endif--instance Costrong (->) where-  unfirst f a = b where (b, d) = f (a, d)-  unsecond f a = b where (d, b) = f (d, a)--instance Functor f => Costrong (Costar f) where-  unfirst (Costar f) = Costar f'-    where f' fa = b where (b, d) = f ((\a -> (a, d)) <$> fa)-  unsecond (Costar f) = Costar f'-    where f' fa = b where (d, b) = f ((,) d <$> fa)--instance Costrong Tagged where-  unfirst (Tagged bd) = Tagged (fst bd)-  unsecond (Tagged db) = Tagged (snd db)--instance ArrowLoop p => Costrong (WrappedArrow p) where-  unfirst (WrapArrow k) = WrapArrow (loop k)--instance MonadFix m => Costrong (Kleisli m) where-  unfirst (Kleisli f) = Kleisli (liftM fst . mfix . f')-    where f' x y = f (x, snd y)--instance Functor f => Costrong (Cokleisli f) where-  unfirst (Cokleisli f) = Cokleisli f'-    where f' fa = b where (b, d) = f ((\a -> (a, d)) <$> fa)------------------------------------------------------------------------------------- * Costrength for Either-----------------------------------------------------------------------------------class Profunctor p => Cochoice p where-  unleft  :: p (Either a d) (Either b d) -> p a b-  unleft = unright . dimap (either Right Left) (either Right Left)--  unright :: p (Either d a) (Either d b) -> p a b-  unright = unleft . dimap (either Right Left) (either Right Left)--#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 708-  {-# MINIMAL unleft | unright #-}-#endif--instance Cochoice (->) where-  unleft f = go . Left where go = either id (go . Right) . f-  unright f = go . Right where go = either (go . Left) id . f--instance Applicative f => Cochoice (Costar f) where-  unleft (Costar f) = Costar (go . fmap Left)-    where go = either id (go . pure . Right) . f---- NB: Another instance that's highly questionable-instance Traversable f => Cochoice (Star f) where-  unright (Star f) = Star (go . Right)-    where go = either (go . Left) id . sequence . f+import Data.Profunctor.Choice+import Data.Profunctor.Closed+import Data.Profunctor.Mapping+import Data.Profunctor.Strong+import Data.Profunctor.Types
src/Data/Profunctor/Adjunction.hs view
@@ -2,9 +2,19 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE RankNTypes #-}+-----------------------------------------------------------------------------+-- |+-- Copyright   :  (C) 2015 Edward Kmett+-- License     :  BSD-style (see the file LICENSE)+--+-- Maintainer  :  Edward Kmett <ekmett@gmail.com>+-- Stability   :  experimental+-- Portability :  non-portable, MPTCs, fundeps+--+---------------------------------------------------------------------------- module Data.Profunctor.Adjunction where -import Data.Profunctor+import Data.Profunctor.Types import Data.Profunctor.Monad  class (ProfunctorFunctor f, ProfunctorFunctor u) => ProfunctorAdjunction f u | f -> u, u -> f where
src/Data/Profunctor/Cayley.hs view
@@ -4,7 +4,7 @@ #endif ----------------------------------------------------------------------------- -- |--- Copyright   :  (C) 2014 Edward Kmett+-- Copyright   :  (C) 2014-2015 Edward Kmett -- License     :  BSD-style (see the file LICENSE) -- -- Maintainer  :  Edward Kmett <ekmett@gmail.com>@@ -80,3 +80,6 @@  instance (Applicative f, ArrowPlus p) => ArrowPlus (Cayley f p) where   Cayley f <+> Cayley g = Cayley (liftA2 (<+>) f g)++-- instance Adjunction f g => ProfunctorAdjunction (Cayley f) (Cayley g) where+  
+ src/Data/Profunctor/Choice.hs view
@@ -0,0 +1,364 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE MultiParamTypeClasses #-}+#if __GLASGOW_HASKELL__ >= 702 && __GLASGOW_HASKELL__ <= 708+{-# LANGUAGE Trustworthy #-}+#endif+-----------------------------------------------------------------------------+-- |+-- Copyright   :  (C) 2014-2015 Edward Kmett+-- License     :  BSD-style (see the file LICENSE)+--+-- Maintainer  :  Edward Kmett <ekmett@gmail.com>+-- Stability   :  provisional+-- Portability :  Rank2Types+--+----------------------------------------------------------------------------+module Data.Profunctor.Choice+  (+  -- * Strength+    Choice(..)+  , TambaraSum(..)+  , tambaraSum, untambaraSum+  , PastroSum(..)+  -- * Costrength+  , Cochoice(..)+  , CotambaraSum(..)+  , cotambaraSum, uncotambaraSum+  , CopastroSum(..)+  ) where++import Control.Applicative hiding (WrappedArrow(..))+import Control.Arrow+import Control.Category+import Control.Comonad+import Data.Bifunctor.Joker (Joker(..))+import Data.Bifunctor.Product (Product(..))+import Data.Bifunctor.Tannen (Tannen(..))+import Data.Monoid hiding (Product)+import Data.Profunctor.Adjunction+import Data.Profunctor.Monad+import Data.Profunctor.Strong+import Data.Profunctor.Types+import Data.Profunctor.Unsafe+import Data.Tagged+#if __GLASGOW_HASKELL__ < 710+import Data.Traversable+import Prelude hiding (id,(.),sequence)+#else+import Prelude hiding (id,(.))+#endif++------------------------------------------------------------------------------+-- Choice+------------------------------------------------------------------------------++-- | 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.+class Profunctor p => Choice p where+  left'  :: p a b -> p (Either a c) (Either b c)+  left' =  dimap (either Right Left) (either Right Left) . right'++  right' :: p a b -> p (Either c a) (Either c b)+  right' =  dimap (either Right Left) (either Right Left) . left'++#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 708+  {-# MINIMAL left' | right' #-}+#endif++instance Choice (->) where+  left' ab (Left a) = Left (ab a)+  left' _ (Right c) = Right c+  {-# INLINE left' #-}+  right' = fmap+  {-# INLINE right' #-}++instance Monad m => Choice (Kleisli m) where+  left' = left+  {-# INLINE left' #-}+  right' = right+  {-# INLINE right' #-}++instance Applicative f => Choice (Star f) where+  left' (Star f) = Star $ either (fmap Left . f) (pure . Right)+  {-# INLINE left' #-}+  right' (Star f) = Star $ either (pure . Left) (fmap Right . f)+  {-# INLINE right' #-}++-- | 'extract' approximates 'costrength'+instance Comonad w => Choice (Cokleisli w) where+  left' = left+  {-# INLINE left' #-}+  right' = right+  {-# INLINE right' #-}++-- NB: This instance is highly questionable+instance Traversable w => Choice (Costar w) where+  left' (Costar wab) = Costar (either Right Left . fmap wab . traverse (either Right Left))+  {-# INLINE left' #-}+  right' (Costar wab) = Costar (fmap wab . sequence)+  {-# INLINE right' #-}++instance Choice Tagged where+  left' (Tagged b) = Tagged (Left b)+  {-# INLINE left' #-}+  right' (Tagged b) = Tagged (Right b)+  {-# INLINE right' #-}++instance ArrowChoice p => Choice (WrappedArrow p) where+  left' (WrapArrow k) = WrapArrow (left k)+  {-# INLINE left' #-}+  right' (WrapArrow k) = WrapArrow (right k)+  {-# INLINE right' #-}++instance Monoid r => Choice (Forget r) where+  left' (Forget k) = Forget (either k (const mempty))+  {-# INLINE left' #-}+  right' (Forget k) = Forget (either (const mempty) k)+  {-# INLINE right' #-}++instance Functor f => Choice (Joker f) where+  left' (Joker fb) = Joker (fmap Left fb)+  {-# INLINE left' #-}+  right' (Joker fb) = Joker (fmap Right fb)+  {-# INLINE right' #-}++instance (Choice p, Choice q) => Choice (Product p q) where+  left' (Pair p q) = Pair (left' p) (left' q)+  {-# INLINE left' #-}+  right' (Pair p q) = Pair (right' p) (right' q)+  {-# INLINE right' #-}++instance (Functor f, Choice p) => Choice (Tannen f p) where+  left' (Tannen fp) = Tannen (fmap left' fp)+  {-# INLINE left' #-}+  right' (Tannen fp) = Tannen (fmap right' fp)+  {-# INLINE right' #-}++instance Choice p => Choice (Tambara p) where+  left' (Tambara f) = Tambara $ dimap hither yon $ left' f where+    hither :: (Either a b, c) -> Either (a, c) (b, c)+    hither (Left y, s) = Left (y, s)+    hither (Right z, s) = Right (z, s)++    yon :: Either (a, c) (b, c) -> (Either a b, c)+    yon (Left (y, s)) = (Left y, s)+    yon (Right (z, s)) = (Right z, s)+++----------------------------------------------------------------------------+-- * TambaraSum+----------------------------------------------------------------------------++-- | TambaraSum is cofreely adjoins strength with respect to Either.+--+-- Note: this is not dual to 'Data.Profunctor.Tambara.Tambara'. It is 'Data.Profunctor.Tambara.Tambara' with respect to a different tensor.+newtype TambaraSum p a b = TambaraSum { runTambaraSum :: forall c. p (Either a c) (Either b c) }++instance ProfunctorFunctor TambaraSum where+  promap f (TambaraSum p) = TambaraSum (f p)++instance ProfunctorComonad TambaraSum where+  proextract (TambaraSum p)   = dimap Left (\(Left a) -> a) p+  produplicate (TambaraSum p) = TambaraSum (TambaraSum $ dimap hither yon p) where+    hither :: Either (Either a b) c -> Either a (Either b c)+    hither (Left (Left x))   = Left x+    hither (Left (Right y))  = Right (Left y)+    hither (Right z)         = Right (Right z)++    yon    :: Either a (Either b c) -> Either (Either a b) c+    yon    (Left x)          = Left (Left x)+    yon    (Right (Left y))  = Left (Right y)+    yon    (Right (Right z)) = Right z++instance Profunctor p => Profunctor (TambaraSum p) where+  dimap f g (TambaraSum p) = TambaraSum $ dimap (left f) (left g) p+  {-# INLINE dimap #-}++instance Profunctor p => Choice (TambaraSum p) where+  left' = runTambaraSum . produplicate+  {-# INLINE left' #-}++instance Category p => Category (TambaraSum p) where+  id = TambaraSum id+  TambaraSum p . TambaraSum q = TambaraSum (p . q)++instance Profunctor p => Functor (TambaraSum p a) where+  fmap = rmap++-- |+-- @+-- 'tambaraSum' '.' 'untambaraSum' ≡ 'id'+-- 'untambaraSum' '.' 'tambaraSum' ≡ 'id'+-- @+tambaraSum :: Choice p => (p :-> q) -> p :-> TambaraSum q+tambaraSum f p = TambaraSum $ f $ left' p++-- |+-- @+-- 'tambaraSum' '.' 'untambaraSum' ≡ 'id'+-- 'untambaraSum' '.' 'tambaraSum' ≡ 'id'+-- @+untambaraSum :: Profunctor q => (p :-> TambaraSum q) -> p :-> q+untambaraSum f p = dimap Left (\(Left a) -> a) $ runTambaraSum $ f p++----------------------------------------------------------------------------+-- * PastroSum+----------------------------------------------------------------------------++-- | PastroSum -| TambaraSum+--+-- PastroSum freely constructs strength with respect to Either.+data PastroSum p a b where+  PastroSum :: (Either y z -> b) -> p x y -> (a -> Either x z) -> PastroSum p a b++instance Profunctor (PastroSum p) where+  dimap f g (PastroSum l m r) = PastroSum (g . l) m (r . f)+  lmap f (PastroSum l m r) = PastroSum l m (r . f)+  rmap g (PastroSum l m r) = PastroSum (g . l) m r+  w #. PastroSum l m r = PastroSum (w #. l) m r+  PastroSum l m r .# w = PastroSum l m (r .# w)++instance ProfunctorAdjunction PastroSum TambaraSum where+  counit (PastroSum f (TambaraSum g) h) = dimap h f g+  unit p = TambaraSum $ PastroSum id p id++instance ProfunctorFunctor PastroSum where+  promap f (PastroSum l m r) = PastroSum l (f m) r++instance ProfunctorMonad PastroSum where+  proreturn p = PastroSum (\(Left a)-> a) p Left+  projoin (PastroSum l (PastroSum m n o) q) = PastroSum lm n oq where+    oq a = case q a of+      Left b -> Left <$> o b+      Right z -> Right (Right z)+    lm (Left x) = l $ Left $ m $ Left x+    lm (Right (Left y)) = l $ Left $ m $ Right y+    lm (Right (Right z)) = l $ Right z++instance Choice (PastroSum p) where+  left' (PastroSum l m r) = PastroSum l' m r' where+    r' = either (fmap Left . r) (Right . Right)+    l' (Left y)          = Left (l (Left y))+    l' (Right (Left z))  = Left (l (Right z))+    l' (Right (Right c)) = Right c+  right' (PastroSum l m r) = PastroSum l' m r' where+    r' = either (Right . Left) (fmap Right . r)+    l' (Right (Left c))  = Left c+    l' (Right (Right z)) = Right (l (Right z))+    l' (Left y)          = Right (l (Left y))++--------------------------------------------------------------------------------+-- * Costrength for Either+--------------------------------------------------------------------------------++class Profunctor p => Cochoice p where+  unleft  :: p (Either a d) (Either b d) -> p a b+  unleft = unright . dimap (either Right Left) (either Right Left)++  unright :: p (Either d a) (Either d b) -> p a b+  unright = unleft . dimap (either Right Left) (either Right Left)++#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 708+  {-# MINIMAL unleft | unright #-}+#endif++instance Cochoice (->) where+  unleft f = go . Left where go = either id (go . Right) . f+  unright f = go . Right where go = either (go . Left) id . f++instance Applicative f => Cochoice (Costar f) where+  unleft (Costar f) = Costar (go . fmap Left)+    where go = either id (go . pure . Right) . f++-- NB: Another instance that's highly questionable+instance Traversable f => Cochoice (Star f) where+  unright (Star f) = Star (go . Right)+    where go = either (go . Left) id . sequence . f++instance (Functor f, Cochoice p) => Cochoice (Tannen f p) where+  unleft (Tannen fp) = Tannen (fmap unleft fp)+  {-# INLINE unleft #-}+  unright (Tannen fp) = Tannen (fmap unright fp)+  {-# INLINE unright #-}++instance (Cochoice p, Cochoice q) => Cochoice (Product p q) where+  unleft (Pair p q) = Pair (unleft p) (unleft q)+  unright (Pair p q) = Pair (unright p) (unright q)++----------------------------------------------------------------------------+-- * CotambaraSum+----------------------------------------------------------------------------++-- | 'CotambaraSum' cofreely constructs costrength with respect to 'Either' (aka 'Choice')+data CotambaraSum q a b where+    CotambaraSum :: Cochoice r => (r :-> q) -> r a b -> CotambaraSum q a b++instance Profunctor (CotambaraSum p) where+  lmap f (CotambaraSum n p) = CotambaraSum n (lmap f p)+  rmap g (CotambaraSum n p) = CotambaraSum n (rmap g p)+  dimap f g (CotambaraSum n p) = CotambaraSum n (dimap f g p)++instance ProfunctorFunctor CotambaraSum where+  promap f (CotambaraSum n p) = CotambaraSum (f . n) p++instance ProfunctorComonad CotambaraSum where+  proextract (CotambaraSum n p)  = n p+  produplicate (CotambaraSum n p) = CotambaraSum id (CotambaraSum n p)++instance Cochoice (CotambaraSum p) where+  unleft (CotambaraSum n p) = CotambaraSum n (unleft p)+  unright (CotambaraSum n p) = CotambaraSum n (unright p)++instance Functor (CotambaraSum p a) where+  fmap = rmap++-- |+-- @+-- 'cotambaraSum' '.' 'uncotambaraSum' ≡ 'id'+-- 'uncotambaraSum' '.' 'cotambaraSum' ≡ 'id'+-- @+cotambaraSum :: Cochoice p => (p :-> q) -> p :-> CotambaraSum q+cotambaraSum = CotambaraSum++-- |+-- @+-- 'cotambaraSum' '.' 'uncotambaraSum' ≡ 'id'+-- 'uncotambaraSum' '.' 'cotambaraSum' ≡ 'id'+-- @+uncotambaraSum :: Profunctor q => (p :-> CotambaraSum q) -> p :-> q+uncotambaraSum f p = proextract (f p)++----------------------------------------------------------------------------+-- * Copastro+----------------------------------------------------------------------------++-- | CopastroSum -| CotambaraSum+--+-- 'CopastroSum' freely constructs costrength with respect to 'Either' (aka 'Choice')+newtype CopastroSum p a b = CopastroSum { runCopastroSum :: forall r. Cochoice r => (forall x y. p x y -> r x y) -> r a b }++instance Profunctor (CopastroSum p) where+  dimap f g (CopastroSum h) = CopastroSum $ \ n -> dimap f g (h n)+  lmap f (CopastroSum h) = CopastroSum $ \ n -> lmap f (h n)+  rmap g (CopastroSum h) = CopastroSum $ \ n -> rmap g (h n)++instance ProfunctorAdjunction CopastroSum CotambaraSum where+ unit p = CotambaraSum id (proreturn p)+ counit (CopastroSum h) = proextract (h id)++instance ProfunctorFunctor CopastroSum where+  promap f (CopastroSum h) = CopastroSum $ \n -> h (n . f)++instance ProfunctorMonad CopastroSum where+  proreturn p = CopastroSum $ \n -> n p+  projoin p = CopastroSum $ \c -> runCopastroSum p (\x -> runCopastroSum x c)++instance Cochoice (CopastroSum p) where+  unleft (CopastroSum p) = CopastroSum $ \n -> unleft (p n)+  unright (CopastroSum p) = CopastroSum $ \n -> unright (p n)
src/Data/Profunctor/Closed.hs view
@@ -3,29 +3,45 @@ {-# LANGUAGE RankNTypes #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE MultiParamTypeClasses #-}-#if __GLASGOW_HASKELL__ >= 702 && __GLASGOW_HASKELL__ <= 708++#if __GLASGOW_HASKELL__ >= 704 && __GLASGOW_HASKELL__ < 708 {-# LANGUAGE Trustworthy #-} #endif +-----------------------------------------------------------------------------+-- |+-- Copyright   :  (C) 2014-2015 Edward Kmett+-- License     :  BSD-style (see the file LICENSE)+--+-- Maintainer  :  Edward Kmett <ekmett@gmail.com>+-- Stability   :  experimental+-- Portability :  portable+--+---------------------------------------------------------------------------- module Data.Profunctor.Closed   ( Closed(..)   , Closure(..)   , close   , unclose   , Environment(..)+  , curry'   ) where  import Control.Applicative import Control.Arrow import Control.Category import Control.Comonad+import Data.Bifunctor.Product (Product(..))+import Data.Bifunctor.Tannen (Tannen(..)) import Data.Distributive-import Data.Monoid-import Data.Profunctor+import Data.Monoid hiding (Product) import Data.Profunctor.Adjunction import Data.Profunctor.Monad+import Data.Profunctor.Strong+import Data.Profunctor.Types import Data.Profunctor.Unsafe import Data.Tagged+import Data.Tuple import Prelude hiding ((.),id)  --------------------------------------------------------------------------------@@ -56,9 +72,18 @@ instance (Distributive f, Monad f) => Closed (Kleisli f) where   closed (Kleisli afb) = Kleisli $ \xa -> distribute $ \x -> afb (xa x) +instance (Closed p, Closed q) => Closed (Product p q) where+  closed (Pair p q) = Pair (closed p) (closed q)++instance (Functor f, Closed p) => Closed (Tannen f p) where+  closed (Tannen fp) = Tannen (fmap closed fp)+ -- instance Monoid r => Closed (Forget r) where --  closed _ = Forget $ \_ -> mempty +curry' :: Closed p => p (a, b) c -> p a (b -> c)+curry' = lmap (,) . closed+ -------------------------------------------------------------------------------- -- * Closure --------------------------------------------------------------------------------@@ -150,7 +175,7 @@ data Environment p a b where   Environment :: ((z -> y) -> b) -> p x y -> (a -> z -> x) -> Environment p a b -instance Profunctor p => Profunctor (Environment p) where+instance Profunctor (Environment p) where   dimap f g (Environment l m r) = Environment (g . l) m (r . f)   lmap f (Environment l m r) = Environment l m (r . f)   rmap g (Environment l m r) = Environment (g . l) m r@@ -169,3 +194,8 @@ instance ProfunctorAdjunction Environment Closure where   counit (Environment g (Closure p) f) = dimap f g p   unit p = Closure (Environment id p id)++instance Closed (Environment p) where+  closed (Environment l m r) = Environment l' m r' where+    r' wa (z,w) = r (wa w) z+    l' zx2y x = l (\z -> zx2y (z,x))
− src/Data/Profunctor/Codensity.hs
@@ -1,54 +0,0 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE Rank2Types #-}-{-# LANGUAGE TypeFamilies #-}-#if __GLASGOW_HASKELL__ >= 702 && __GLASGOW_HASKELL__ <= 708-{-# LANGUAGE Trustworthy #-}-#endif--------------------------------------------------------------------------------- |--- Copyright   :  (C) 2014 Edward Kmett--- License     :  BSD-style (see the file LICENSE)------ Maintainer  :  Edward Kmett <ekmett@gmail.com>--- Stability   :  provisional--- Portability :  Rank2Types, TFs---------------------------------------------------------------------------------module Data.Profunctor.Codensity-  ( Codensity(..)-  , decomposeCodensity-  ) where--import Control.Category-import Data.Profunctor.Unsafe-import Data.Profunctor.Composition-import Prelude hiding (id,(.))---- | This represents the right Kan extension of a 'Profunctor' @p@ along itself. This provides a generalization of the \"difference list\" trick to profunctors.-newtype Codensity p a b = Codensity { runCodensity :: forall x. p x a -> p x b }--instance Profunctor p => Profunctor (Codensity p) where-  dimap ca bd f = Codensity (rmap bd . runCodensity f . rmap ca)-  {-# INLINE dimap #-}-  lmap ca f = Codensity (runCodensity f . rmap ca)-  {-# INLINE lmap #-}-  rmap bd f = Codensity (rmap bd . runCodensity f)-  {-# INLINE rmap #-}-  bd #. f = Codensity (\p -> bd #. runCodensity f p)-  {-# INLINE ( #. ) #-}-  f .# ca = Codensity (\p -> runCodensity f (ca #. p))-  {-# INLINE (.#) #-}--instance Profunctor p => Functor (Codensity p a) where-  fmap bd f = Codensity (rmap bd . runCodensity f)-  {-# INLINE fmap #-}--instance Category (Codensity p) where-  id = Codensity id-  {-# INLINE id #-}-  Codensity f . Codensity g = Codensity (f . g)-  {-# INLINE (.) #-}--decomposeCodensity :: Procompose (Codensity p) p a b -> p a b-decomposeCodensity (Procompose (Codensity pp) p) = pp p-{-# INLINE decomposeCodensity #-}
src/Data/Profunctor/Composition.hs view
@@ -11,7 +11,7 @@ ----------------------------------------------------------------------------- -- | -- Module      :  Data.Profunctor.Composition--- Copyright   :  (C) 2014 Edward Kmett+-- Copyright   :  (C) 2014-2015 Edward Kmett -- License     :  BSD-style (see the file LICENSE) -- -- Maintainer  :  Edward Kmett <ekmett@gmail.com>@@ -28,6 +28,9 @@   , idl   , idr   , assoc+  -- * Categories as monoid objects+  , eta+  , mu   -- * Generalized Composition   , stars, kleislis   , costars, cokleislis@@ -43,7 +46,6 @@ import Data.Functor.Compose import Data.Profunctor import Data.Profunctor.Adjunction-import Data.Profunctor.Closed import Data.Profunctor.Monad import Data.Profunctor.Rep import Data.Profunctor.Sieve@@ -227,6 +229,7 @@ ---------------------------------------------------------------------------- -- * 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 { runRift :: forall x. p b x -> q a x } @@ -272,3 +275,16 @@   unit q = Rift $ \p -> Procompose p q  --instance (ProfunctorAdjunction f g, ProfunctorAdjunction f' g') => ProfunctorAdjunction (ProfunctorCompose f' f) (ProfunctorCompose g g') where++----------------------------------------------------------------------------+-- * Monoids+----------------------------------------------------------------------------+++-- | a 'Category' that is also a 'Profunctor' is a 'Monoid' in @Prof@++eta :: (Profunctor p, Category p) => (->) :-> p+eta f = rmap f id++mu :: Category p => Procompose p p :-> p+mu (Procompose f g) = f . g
+ src/Data/Profunctor/Mapping.hs view
@@ -0,0 +1,108 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE RankNTypes #-}+module Data.Profunctor.Mapping+  ( Mapping(..)+  , CofreeMapping(..)+  , FreeMapping(..)+  -- * Closed in terms of Mapping+  , traverseMapping+  , closedMapping+  ) where++import Control.Arrow (Kleisli(..))+import Data.Distributive+import Data.Functor.Compose+import Data.Functor.Identity+import Data.Profunctor.Choice+import Data.Profunctor.Closed+import Data.Profunctor.Monad+import Data.Profunctor.Strong+import Data.Profunctor.Traversing+import Data.Profunctor.Types+import Data.Profunctor.Unsafe+#if __GLASGOW_HASKELL__ < 710+import Control.Applicative+#endif++class (Traversing p, Closed p) => Mapping p where+  map' :: Functor f => p a b -> p (f a) (f b)++instance Mapping (->) where+  map' = fmap++instance (Monad m, Distributive m) => Mapping (Kleisli m) where+  map' (Kleisli f) = Kleisli (collect f)++-- see <https://github.com/ekmett/distributive/issues/12>+instance (Applicative m, Distributive m) => Mapping (Star m) where+  map' (Star f) = Star (collect f)++traverseMapping :: (Mapping p, Functor f) => p a b -> p (f a) (f b)+traverseMapping = map'++closedMapping :: Mapping p => p a b -> p (x -> a) (x -> b)+closedMapping = map'++newtype CofreeMapping p a b = CofreeMapping { runCofreeMapping :: forall f. Functor f => p (f a) (f b) }++instance Profunctor p => Profunctor (CofreeMapping p) where+  lmap f (CofreeMapping p) = CofreeMapping (lmap (fmap f) p)+  rmap g (CofreeMapping p) = CofreeMapping (rmap (fmap g) p)+  dimap f g (CofreeMapping p) = CofreeMapping (dimap (fmap f) (fmap g) p)++instance Profunctor p => Strong (CofreeMapping p) where+  second' = map'++instance Profunctor p => Choice (CofreeMapping p) where+  right' = map'++instance Profunctor p => Closed (CofreeMapping p) where+  closed = map'++instance Profunctor p => Traversing (CofreeMapping p) where+  traverse' = map'++instance Profunctor p => Mapping (CofreeMapping p) where+  -- !@(#*&() Compose isn't representational in its second arg or we could use #. and .#+  map' (CofreeMapping p) = CofreeMapping (dimap Compose getCompose p)++instance ProfunctorFunctor CofreeMapping where+  promap f (CofreeMapping p) = CofreeMapping (f p)++instance ProfunctorComonad CofreeMapping where+  proextract (CofreeMapping p) = runIdentity #. p .# Identity+  produplicate (CofreeMapping p) = CofreeMapping (CofreeMapping (dimap Compose getCompose p))++-- | @FreeMapping -| CofreeMapping@+data FreeMapping p a b where+  FreeMapping :: Functor f => (f y -> b) -> p x y -> (a -> f x) -> FreeMapping p a b++instance Profunctor (FreeMapping p) where+  lmap f (FreeMapping l m r) = FreeMapping l m (r . f)+  rmap g (FreeMapping l m r) = FreeMapping (g . l) m r+  dimap f g (FreeMapping l m r) = FreeMapping (g . l) m (r . f)+  g #. FreeMapping l m r = FreeMapping (g #. l) m r+  FreeMapping l m r .# f = FreeMapping l m (r .# f)++instance Strong (FreeMapping p) where+  second' = map'++instance Choice (FreeMapping p) where+  right' = map'++instance Closed (FreeMapping p) where+  closed = map'++instance Traversing (FreeMapping p) where+  traverse' = map'++instance Mapping (FreeMapping p) where+  map' (FreeMapping l m r) = FreeMapping (fmap l .# getCompose) m (Compose #. fmap r)++instance ProfunctorFunctor FreeMapping where+  promap f (FreeMapping l m r) = FreeMapping l (f m) r++instance ProfunctorMonad FreeMapping where+  proreturn p = FreeMapping runIdentity p Identity+  projoin (FreeMapping l (FreeMapping l' m r') r) = FreeMapping ((l . fmap l') .# getCompose) m (Compose #. (fmap r' . r))
src/Data/Profunctor/Monad.hs view
@@ -1,16 +1,62 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE TypeOperators #-}+-----------------------------------------------------------------------------+-- |+-- Copyright   :  (C) 2014-2015 Edward Kmett+-- License     :  BSD-style (see the file LICENSE)+--+-- Maintainer  :  Edward Kmett <ekmett@gmail.com>+-- Stability   :  experimental+-- Portability :  portable+--+---------------------------------------------------------------------------- module Data.Profunctor.Monad where -import Data.Profunctor+import Control.Comonad+import Data.Bifunctor.Tannen+import Data.Bifunctor.Product+import Data.Bifunctor.Sum+import Data.Profunctor.Types  class ProfunctorFunctor t where   promap    :: Profunctor p => (p :-> q) -> t p :-> t q +instance Functor f => ProfunctorFunctor (Tannen f) where+  promap f (Tannen g) = Tannen (fmap f g)++instance ProfunctorFunctor (Product p) where+  promap f (Pair p q) = Pair p (f q)++instance ProfunctorFunctor (Sum p) where+  promap _ (L2 p) = L2 p+  promap f (R2 q) = R2 (f q)+ class ProfunctorFunctor t => ProfunctorMonad t where   proreturn :: Profunctor p => p :-> t p   projoin   :: Profunctor p => t (t p) :-> t p +#if __GLASGOW_HASKELL__ < 710+instance (Functor f, Monad f) => ProfunctorMonad (Tannen f) where+#else+instance Monad f => ProfunctorMonad (Tannen f) where+#endif+  proreturn = Tannen . return+  projoin (Tannen m) = Tannen $ m >>= runTannen++instance ProfunctorMonad (Sum p) where+  proreturn = R2+  projoin (L2 p) = L2 p+  projoin (R2 m) = m+ class ProfunctorFunctor t => ProfunctorComonad t where   proextract :: Profunctor p => t p :-> p   produplicate :: Profunctor p => t p :-> t (t p)++instance Comonad f => ProfunctorComonad (Tannen f) where+  proextract = extract . runTannen+  produplicate (Tannen w) = Tannen $ extend Tannen w++instance ProfunctorComonad (Product p) where+  proextract (Pair _ q) = q+  produplicate pq@(Pair p _) = Pair p pq
− src/Data/Profunctor/Monoid.hs
@@ -1,16 +0,0 @@-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE NoImplicitPrelude #-}-module Data.Profunctor.Monoid where--import Control.Category-import Data.Profunctor-import Data.Profunctor.Composition---- | a 'Category' that is also a 'Profunctor' is a 'Monoid' in @Prof@--eta :: (Profunctor p, Category p) => (->) :-> p-eta f = rmap f id--mu :: Category p => Procompose p p :-> p-mu (Procompose f g) = f . g
src/Data/Profunctor/Ran.hs view
@@ -7,7 +7,7 @@ #endif ----------------------------------------------------------------------------- -- |--- Copyright   :  (C) 2013-2014 Edward Kmett and Dan Doel+-- Copyright   :  (C) 2013-2015 Edward Kmett and Dan Doel -- License     :  BSD-style (see the file LICENSE) -- -- Maintainer  :  Edward Kmett <ekmett@gmail.com>@@ -21,6 +21,8 @@   , precomposeRan   , curryRan   , uncurryRan+  , Codensity(..)+  , decomposeCodensity   ) where  import Control.Category@@ -30,6 +32,10 @@ import Data.Profunctor.Unsafe import Prelude hiding (id,(.)) +--------------------------------------------------------------------------------+-- * Ran+--------------------------------------------------------------------------------+ -- | This represents the right Kan extension 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 Ran p q a b = Ran { runRan :: forall x. p x a -> q x b } @@ -81,3 +87,36 @@ uncurryRan :: (p :-> Ran q r) -> Procompose p q :-> r uncurryRan f (Procompose p q) = runRan (f p) q {-# INLINE uncurryRan #-}++--------------------------------------------------------------------------------+-- * Codensity+--------------------------------------------------------------------------------++-- | This represents the right Kan extension of a 'Profunctor' @p@ along itself. This provides a generalization of the \"difference list\" trick to profunctors.+newtype Codensity p a b = Codensity { runCodensity :: forall x. p x a -> p x b }++instance Profunctor p => Profunctor (Codensity p) where+  dimap ca bd f = Codensity (rmap bd . runCodensity f . rmap ca)+  {-# INLINE dimap #-}+  lmap ca f = Codensity (runCodensity f . rmap ca)+  {-# INLINE lmap #-}+  rmap bd f = Codensity (rmap bd . runCodensity f)+  {-# INLINE rmap #-}+  bd #. f = Codensity (\p -> bd #. runCodensity f p)+  {-# INLINE ( #. ) #-}+  f .# ca = Codensity (\p -> runCodensity f (ca #. p))+  {-# INLINE (.#) #-}++instance Profunctor p => Functor (Codensity p a) where+  fmap bd f = Codensity (rmap bd . runCodensity f)+  {-# INLINE fmap #-}++instance Category (Codensity p) where+  id = Codensity id+  {-# INLINE id #-}+  Codensity f . Codensity g = Codensity (f . g)+  {-# INLINE (.) #-}++decomposeCodensity :: Procompose (Codensity p) p a b -> p a b+decomposeCodensity (Procompose (Codensity pp) p) = pp p+{-# INLINE decomposeCodensity #-}
src/Data/Profunctor/Rep.hs view
@@ -30,6 +30,7 @@   , Corepresentable(..)   , cotabulated   , unfirstCorep, unsecondCorep+  , closedCorep   -- * Prep -| Star   , Prep(..)   , prepAdj@@ -89,7 +90,14 @@   tabulate = Forget . (getConst .)   {-# INLINE tabulate #-} +{- TODO: coproducts and products+instance (Representable p, Representable q) => Representable (Bifunctor.Product p q)+  type Rep (Bifunctor.Product p q) = Functor.Product p q +instance (Corepresentable p, Corepresentable q) => Corepresentable (Bifunctor.Product p q) where+  type Rep (Bifunctor.Product p q) = Functor.Sum p q+-}+ type Iso s t a b = forall p f. (Profunctor p, Functor f) => p a (f b) -> p s (f t)  -- | 'tabulate' and 'sieve' form two halves of an isomorphism.@@ -109,15 +117,19 @@   type Corep p :: * -> *   cotabulate :: (Corep p d -> c) -> p d c --- | Default definition for 'unfirst' given that p is 'Corepresentable'.+-- | Default definition for 'unfirst' given that @p@ is 'Corepresentable'. unfirstCorep :: Corepresentable p => p (a, d) (b, d) -> p a b unfirstCorep p = cotabulate f   where f fa = b where (b, d) = cosieve p ((\a -> (a, d)) <$> fa) --- | Default definition for 'unsecond' given that p is 'Corepresentable'.+-- | Default definition for 'unsecond' given that @p@ is 'Corepresentable'. unsecondCorep :: Corepresentable p => p (d, a) (d, b) -> p a b unsecondCorep p = cotabulate f   where f fa = b where (d, b) = cosieve p ((,) d <$> fa)++-- | Default definition for 'closed' given that @p@ is 'Corepresentable'+closedCorep :: Corepresentable p => p a b -> p (x -> a) (x -> b)+closedCorep p = cotabulate $ \fs x -> cosieve p (fmap ($x) fs)  instance Corepresentable (->) where   type Corep (->) = Identity
+ src/Data/Profunctor/Strong.hs view
@@ -0,0 +1,390 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE MultiParamTypeClasses #-}++#if __GLASGOW_HASKELL__ >= 704 && __GLASGOW_HASKELL__ < 708+{-# LANGUAGE Trustworthy #-}+#endif++-----------------------------------------------------------------------------+-- |+-- Copyright   :  (C) 2014-2015 Edward Kmett+-- License     :  BSD-style (see the file LICENSE)+--+-- Maintainer  :  Edward Kmett <ekmett@gmail.com>+-- Stability   :  provisional+-- Portability :  Rank2Types+--+----------------------------------------------------------------------------+module Data.Profunctor.Strong+  (+  -- * Strength+    Strong(..)+  , uncurry'+  , Tambara(..)+  , tambara, untambara+  , Pastro(..)+  -- * Costrength+  , Costrong(..)+  , Cotambara(..)+  , cotambara, uncotambara+  , Copastro(..)+  ) where++import Control.Applicative hiding (WrappedArrow(..))+import Control.Arrow+import Control.Category+import Control.Comonad+import Control.Monad (liftM)+import Control.Monad.Fix+import Data.Bifunctor.Clown (Clown(..))+import Data.Bifunctor.Product (Product(..))+import Data.Bifunctor.Tannen (Tannen(..))+import Data.Functor.Contravariant (Contravariant(..))+import Data.Monoid hiding (Product)+import Data.Profunctor.Adjunction+import Data.Profunctor.Monad+import Data.Profunctor.Types+import Data.Profunctor.Unsafe+import Data.Tagged+import Data.Tuple+import Prelude hiding (id,(.))++------------------------------------------------------------------------------+-- Strong+------------------------------------------------------------------------------++-- | 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>+class Profunctor p => Strong p where+  first' :: p a b  -> p (a, c) (b, c)+  first' = dimap swap swap . second'++  second' :: p a b -> p (c, a) (c, b)+  second' = dimap swap swap . first'++#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 708+  {-# MINIMAL first' | second' #-}+#endif++uncurry' :: Strong p => p a (b -> c) -> p (a, b) c+uncurry' = rmap (\(f,x) -> f x) . first'+{-# INLINE uncurry' #-}++instance Strong (->) where+  first' ab ~(a, c) = (ab a, c)+  {-# INLINE first' #-}+  second' ab ~(c, a) = (c, ab a)++instance Monad m => Strong (Kleisli m) where+  first' (Kleisli f) = Kleisli $ \ ~(a, c) -> do+     b <- f a+     return (b, c)+  {-# INLINE first' #-}+  second' (Kleisli f) = Kleisli $ \ ~(c, a) -> do+     b <- f a+     return (c, b)+  {-# INLINE second' #-}++instance Functor m => Strong (Star m) where+  first' (Star f) = Star $ \ ~(a, c) -> (\b' -> (b', c)) <$> f a+  {-# INLINE first' #-}+  second' (Star f) = Star $ \ ~(c, a) -> (,) c <$> f a+  {-# INLINE second' #-}++-- | 'Arrow' is 'Strong' 'Category'+instance Arrow p => Strong (WrappedArrow p) where+  first' (WrapArrow k) = WrapArrow (first k)+  {-# INLINE first' #-}+  second' (WrapArrow k) = WrapArrow (second k)+  {-# INLINE second' #-}++instance Strong (Forget r) where+  first' (Forget k) = Forget (k . fst)+  {-# INLINE first' #-}+  second' (Forget k) = Forget (k . snd)+  {-# INLINE second' #-}++instance Contravariant f => Strong (Clown f) where+  first' (Clown fa) = Clown (contramap fst fa)+  {-# INLINE first' #-}+  second' (Clown fa) = Clown (contramap snd fa)+  {-# INLINE second' #-}++instance (Strong p, Strong q) => Strong (Product p q) where+  first' (Pair p q) = Pair (first' p) (first' q)+  {-# INLINE first' #-}+  second' (Pair p q) = Pair (second' p) (second' q)+  {-# INLINE second' #-}++instance (Functor f, Strong p) => Strong (Tannen f p) where+  first' (Tannen fp) = Tannen (fmap first' fp)+  {-# INLINE first' #-}+  second' (Tannen fp) = Tannen (fmap second' fp)+  {-# INLINE second' #-}++----------------------------------------------------------------------------+-- * Tambara+----------------------------------------------------------------------------++-- | 'Tambara' cofreely makes any 'Profunctor' 'Strong'.+newtype Tambara p a b = Tambara { runTambara :: forall c. p (a, c) (b, c) }++instance Profunctor p => Profunctor (Tambara p) where+  dimap f g (Tambara p) = Tambara $ dimap (first f) (first g) p+  {-# INLINE dimap #-}++instance ProfunctorFunctor Tambara where+  promap f (Tambara p) = Tambara (f p)++instance ProfunctorComonad Tambara where+  proextract (Tambara p) = dimap (\a -> (a,())) fst p+  produplicate (Tambara p) = Tambara (Tambara $ dimap hither yon p) where+    hither :: ((a, b), c) -> (a, (b, c))+    hither ~(~(x,y),z) = (x,(y,z))++    yon    :: (a, (b, c)) -> ((a, b), c)+    yon    ~(x,~(y,z)) = ((x,y),z)++instance Profunctor p => Strong (Tambara p) where+  first' = runTambara . produplicate+  {-# INLINE first' #-}++instance Category p => Category (Tambara p) where+  id = Tambara id+  Tambara p . Tambara q = Tambara (p . q)++instance Arrow p => Arrow (Tambara p) where+  arr f = Tambara $ arr $ first f+  first (Tambara f) = Tambara (arr go . first f . arr go) where+    go :: ((a, b), c) -> ((a, c), b)+    go ~(~(x,y),z) = ((x,z),y)++instance ArrowChoice p => ArrowChoice (Tambara p) where+  left (Tambara f) = Tambara (arr yon . left f . arr hither) where+    hither :: (Either a b, c) -> Either (a, c) (b, c)+    hither (Left y, s) = Left (y, s)+    hither (Right z, s) = Right (z, s)++    yon :: Either (a, c) (b, c) -> (Either a b, c)+    yon (Left (y, s)) = (Left y, s)+    yon (Right (z, s)) = (Right z, s)++instance ArrowApply p => ArrowApply (Tambara p) where+  app = Tambara $ app . arr (\((Tambara f, x), s) -> (f, (x, s)))++instance ArrowLoop p => ArrowLoop (Tambara p) where+  loop (Tambara f) = Tambara (loop (arr go . f . arr go)) where+    go :: ((a, b), c) -> ((a, c), b)+    go ~(~(x,y),z) = ((x,z),y)++instance ArrowZero p => ArrowZero (Tambara p) where+  zeroArrow = Tambara zeroArrow++instance ArrowPlus p => ArrowPlus (Tambara p) where+  Tambara f <+> Tambara g = Tambara (f <+> g)++instance Profunctor p => Functor (Tambara p a) where+  fmap = rmap++instance (Profunctor p, Arrow p) => Applicative (Tambara p a) where+  pure x = arr (const x)+  f <*> g = arr (uncurry id) . (f &&& g)++instance (Profunctor p, ArrowPlus p) => Alternative (Tambara p a) where+  empty = zeroArrow+  f <|> g = f <+> g++instance ArrowPlus p => Monoid (Tambara p a b) where+  mempty = zeroArrow+  mappend f g = f <+> g++-- |+-- @+-- 'tambara' '.' 'untambara' ≡ 'id'+-- 'untambara' '.' 'tambara' ≡ 'id'+-- @+tambara :: Strong p => (p :-> q) -> p :-> Tambara q+tambara f p = Tambara $ f $ first' p++-- |+-- @+-- 'tambara' '.' 'untambara' ≡ 'id'+-- 'untambara' '.' 'tambara' ≡ 'id'+-- @+untambara :: Profunctor q => (p :-> Tambara q) -> p :-> q+untambara f p = dimap (\a -> (a,())) fst $ runTambara $ f p++----------------------------------------------------------------------------+-- * Pastro+----------------------------------------------------------------------------++-- | Pastro -| Tambara+--+-- @+-- Pastro p ~ exists z. Costar ((,)z) `Procompose` p `Procompose` Star ((,)z)+-- @+--+-- 'Pastro' freely makes any 'Profunctor' 'Strong'.+data Pastro p a b where+  Pastro :: ((y, z) -> b) -> p x y -> (a -> (x, z)) -> Pastro p a b++instance Profunctor (Pastro p) where+  dimap f g (Pastro l m r) = Pastro (g . l) m (r . f)+  lmap f (Pastro l m r) = Pastro l m (r . f)+  rmap g (Pastro l m r) = Pastro (g . l) m r+  w #. Pastro l m r = Pastro (w #. l) m r+  Pastro l m r .# w = Pastro l m (r .# w)++instance ProfunctorFunctor Pastro where+  promap f (Pastro l m r) = Pastro l (f m) r++instance ProfunctorMonad Pastro where+  proreturn p = Pastro fst p $ \a -> (a,())+  projoin (Pastro l (Pastro m n o) p) = Pastro lm n op where+    op a = case p a of+      (b, f) -> case o b of+         (c, g) -> (c, (f, g))+    lm (d, (f, g)) = l (m (d, g), f)++instance ProfunctorAdjunction Pastro Tambara where+  counit (Pastro g (Tambara p) f) = dimap f g p+  unit p = Tambara (Pastro id p id)++instance Strong (Pastro p) where+  first' (Pastro l m r) = Pastro l' m r' where+    r' (a,c) = case r a of+      (x,z) -> (x,(z,c))+    l' (y,(z,c)) = (l (y,z), c)+  second' (Pastro l m r) = Pastro l' m r' where+    r' (c,a) = case r a of+      (x,z) -> (x,(c,z))+    l' (y,(c,z)) = (c,l (y,z))++--------------------------------------------------------------------------------+-- * Costrength for (,)+--------------------------------------------------------------------------------++-- | Analogous to 'ArrowLoop', 'loop' = 'unfirst'+class Profunctor p => Costrong p where+  unfirst  :: p (a, d) (b, d) -> p a b+  unfirst = unsecond . dimap swap swap++  unsecond :: p (d, a) (d, b) -> p a b+  unsecond = unfirst . dimap swap swap++#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 708+  {-# MINIMAL unfirst | unsecond #-}+#endif++instance Costrong (->) where+  unfirst f a = b where (b, d) = f (a, d)+  unsecond f a = b where (d, b) = f (d, a)++instance Functor f => Costrong (Costar f) where+  unfirst (Costar f) = Costar f'+    where f' fa = b where (b, d) = f ((\a -> (a, d)) <$> fa)+  unsecond (Costar f) = Costar f'+    where f' fa = b where (d, b) = f ((,) d <$> fa)++instance Costrong Tagged where+  unfirst (Tagged bd) = Tagged (fst bd)+  unsecond (Tagged db) = Tagged (snd db)++instance ArrowLoop p => Costrong (WrappedArrow p) where+  unfirst (WrapArrow k) = WrapArrow (loop k)++instance MonadFix m => Costrong (Kleisli m) where+  unfirst (Kleisli f) = Kleisli (liftM fst . mfix . f')+    where f' x y = f (x, snd y)++instance Functor f => Costrong (Cokleisli f) where+  unfirst (Cokleisli f) = Cokleisli f'+    where f' fa = b where (b, d) = f ((\a -> (a, d)) <$> fa)++instance (Functor f, Costrong p) => Costrong (Tannen f p) where+  unfirst (Tannen fp) = Tannen (fmap unfirst fp)+  unsecond (Tannen fp) = Tannen (fmap unsecond fp)++instance (Costrong p, Costrong q) => Costrong (Product p q) where+  unfirst (Pair p q) = Pair (unfirst p) (unfirst q)+  unsecond (Pair p q) = Pair (unsecond p) (unsecond q)++----------------------------------------------------------------------------+-- * Cotambara+----------------------------------------------------------------------------++-- | Cotambara cofreely constructs costrength+data Cotambara q a b where+    Cotambara :: Costrong r => (r :-> q) -> r a b -> Cotambara q a b++instance Profunctor (Cotambara p) where+  lmap f (Cotambara n p) = Cotambara n (lmap f p)+  rmap g (Cotambara n p) = Cotambara n (rmap g p)+  dimap f g (Cotambara n p) = Cotambara n (dimap f g p)++instance ProfunctorFunctor Cotambara where+  promap f (Cotambara n p) = Cotambara (f . n) p++instance ProfunctorComonad Cotambara where+  proextract (Cotambara n p)  = n p+  produplicate (Cotambara n p) = Cotambara id (Cotambara n p)++instance Costrong (Cotambara p) where+  unfirst (Cotambara n p) = Cotambara n (unfirst p)++instance Functor (Cotambara p a) where+  fmap = rmap++-- |+-- @+-- 'cotambara' '.' 'uncotambara' ≡ 'id'+-- 'uncotambara' '.' 'cotambara' ≡ 'id'+-- @+cotambara :: Costrong p => (p :-> q) -> p :-> Cotambara q+cotambara = Cotambara++-- |+-- @+-- 'cotambara' '.' 'uncotambara' ≡ 'id'+-- 'uncotambara' '.' 'cotambara' ≡ 'id'+-- @+uncotambara :: Profunctor q => (p :-> Cotambara q) -> p :-> q+uncotambara f p = proextract (f p)++----------------------------------------------------------------------------+-- * Copastro+----------------------------------------------------------------------------++-- | Copastro -| Cotambara+--+-- Copastro freely constructs costrength+newtype Copastro p a b = Copastro { runCopastro :: forall r. Costrong r => (forall x y. p x y -> r x y) -> r a b }++instance Profunctor (Copastro p) where+  dimap f g (Copastro h) = Copastro $ \ n -> dimap f g (h n)+  lmap f (Copastro h) = Copastro $ \ n -> lmap f (h n)+  rmap g (Copastro h) = Copastro $ \ n -> rmap g (h n)++instance ProfunctorAdjunction Copastro Cotambara where+ unit p = Cotambara id (proreturn p)+ counit (Copastro h) = proextract (h id)++instance ProfunctorFunctor Copastro where+  promap f (Copastro h) = Copastro $ \n -> h (n . f)++instance ProfunctorMonad Copastro where+  proreturn p = Copastro $ \n -> n p+  projoin p = Copastro $ \c -> runCopastro p (\x -> runCopastro x c)++instance Costrong (Copastro p) where+  unfirst (Copastro p) = Copastro $ \n -> unfirst (p n)+  unsecond (Copastro p) = Copastro $ \n -> unsecond (p n)
− src/Data/Profunctor/Tambara.hs
@@ -1,261 +0,0 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE GADTs #-}-{-# LANGUAGE Rank2Types #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE MultiParamTypeClasses #-}-#if __GLASGOW_HASKELL__ >= 702 && __GLASGOW_HASKELL__ <= 708-{-# LANGUAGE Trustworthy #-}-#endif--------------------------------------------------------------------------------- |--- Copyright   :  (C) 2014 Edward Kmett--- License     :  BSD-style (see the file LICENSE)------ Maintainer  :  Edward Kmett <ekmett@gmail.com>--- Stability   :  provisional--- Portability :  Rank2Types---------------------------------------------------------------------------------module Data.Profunctor.Tambara-  ( Tambara(..)-  , tambara, untambara-  , Pastro(..)-  , Cotambara(..)-  , cotambara, uncotambara-  , Copastro(..)-  ) where--import Control.Applicative-import Control.Arrow-import Control.Category-import Data.Monoid-import Data.Profunctor-import Data.Profunctor.Adjunction-import Data.Profunctor.Monad-import Data.Profunctor.Unsafe-import Prelude hiding (id,(.))--------------------------------------------------------------------------------- * Tambara-------------------------------------------------------------------------------newtype Tambara p a b = Tambara { runTambara :: forall c. p (a, c) (b, c) }--instance Profunctor p => Profunctor (Tambara p) where-  dimap f g (Tambara p) = Tambara $ dimap (first f) (first g) p-  {-# INLINE dimap #-}--instance ProfunctorFunctor Tambara where-  promap f (Tambara p) = Tambara (f p)--instance ProfunctorComonad Tambara where-  proextract (Tambara p) = dimap (\a -> (a,())) fst p-  produplicate (Tambara p) = Tambara (Tambara $ dimap hither yon p) where-    hither :: ((a, b), c) -> (a, (b, c))-    hither ~(~(x,y),z) = (x,(y,z))--    yon    :: (a, (b, c)) -> ((a, b), c)-    yon    ~(x,~(y,z)) = ((x,y),z)--instance Profunctor p => Strong (Tambara p) where-  first' = runTambara . produplicate-  {-# INLINE first' #-}--instance Choice p => Choice (Tambara p) where-  left' (Tambara f) = Tambara $ dimap hither yon $ left' f where-    hither :: (Either a b, c) -> Either (a, c) (b, c)-    hither (Left y, s) = Left (y, s)-    hither (Right z, s) = Right (z, s)--    yon :: Either (a, c) (b, c) -> (Either a b, c)-    yon (Left (y, s)) = (Left y, s)-    yon (Right (z, s)) = (Right z, s)--instance Category p => Category (Tambara p) where-  id = Tambara id-  Tambara p . Tambara q = Tambara (p . q)--instance Arrow p => Arrow (Tambara p) where-  arr f = Tambara $ arr $ first f-  first (Tambara f) = Tambara (arr go . first f . arr go) where-    go :: ((a, b), c) -> ((a, c), b)-    go ~(~(x,y),z) = ((x,z),y)--instance ArrowChoice p => ArrowChoice (Tambara p) where-  left (Tambara f) = Tambara (arr yon . left f . arr hither) where-    hither :: (Either a b, c) -> Either (a, c) (b, c)-    hither (Left y, s) = Left (y, s)-    hither (Right z, s) = Right (z, s)--    yon :: Either (a, c) (b, c) -> (Either a b, c)-    yon (Left (y, s)) = (Left y, s)-    yon (Right (z, s)) = (Right z, s)--instance ArrowApply p => ArrowApply (Tambara p) where-  app = Tambara $ app . arr (\((Tambara f, x), s) -> (f, (x, s)))--instance ArrowLoop p => ArrowLoop (Tambara p) where-  loop (Tambara f) = Tambara (loop (arr go . f . arr go)) where-    go :: ((a, b), c) -> ((a, c), b)-    go ~(~(x,y),z) = ((x,z),y)--instance ArrowZero p => ArrowZero (Tambara p) where-  zeroArrow = Tambara zeroArrow--instance ArrowPlus p => ArrowPlus (Tambara p) where-  Tambara f <+> Tambara g = Tambara (f <+> g)--instance Profunctor p => Functor (Tambara p a) where-  fmap = rmap--instance (Profunctor p, Arrow p) => Applicative (Tambara p a) where-  pure x = arr (const x)-  f <*> g = arr (uncurry id) . (f &&& g)--instance (Profunctor p, ArrowPlus p) => Alternative (Tambara p a) where-  empty = zeroArrow-  f <|> g = f <+> g--instance (Profunctor p, ArrowPlus p) => Monoid (Tambara p a b) where-  mempty = zeroArrow-  mappend f g = f <+> g---- |--- @--- 'tambara' '.' 'untambara' ≡ 'id'--- 'untambara' '.' 'tambara' ≡ 'id'--- @-tambara :: Strong p => (p :-> q) -> p :-> Tambara q-tambara f p = Tambara $ f $ first' p---- |--- @--- 'tambara' '.' 'untambara' ≡ 'id'--- 'untambara' '.' 'tambara' ≡ 'id'--- @-untambara :: Profunctor q => (p :-> Tambara q) -> p :-> q-untambara f p = dimap (\a -> (a,())) fst $ runTambara $ f p--------------------------------------------------------------------------------- * Pastro--------------------------------------------------------------------------------- | Pastro -| Tambara------ @--- Pastro p ~ exists z. Costar ((,)z) `Procompose` p `Procompose` Star ((,)z)--- @-data Pastro p a b where-  Pastro :: ((y, z) -> b) -> p x y -> (a -> (x, z)) -> Pastro p a b--instance Profunctor p => Profunctor (Pastro p) where-  dimap f g (Pastro l m r) = Pastro (g . l) m (r . f)-  lmap f (Pastro l m r) = Pastro l m (r . f)-  rmap g (Pastro l m r) = Pastro (g . l) m r-  w #. Pastro l m r = Pastro (w #. l) m r-  Pastro l m r .# w = Pastro l m (r .# w)--instance ProfunctorFunctor Pastro where-  promap f (Pastro l m r) = Pastro l (f m) r--instance ProfunctorMonad Pastro where-  proreturn p = Pastro fst p $ \a -> (a,())-  projoin (Pastro l (Pastro m n o) p) = Pastro lm n op where-    op a = case p a of-      (b, f) -> case o b of-         (c, g) -> (c, (f, g))-    lm (d, (f, g)) = l (m (d, g), f)--instance ProfunctorAdjunction Pastro Tambara where-  counit (Pastro g (Tambara p) f) = dimap f g p-  unit p = Tambara (Pastro id p id)--------------------------------------------------------------------------------- * Cotambara--------------------------------------------------------------------------------- | Cotambara is freely adjoins respect for cocartesian structure to a profunctor------ Note: this is not dual to 'Tambara'. It is 'Tambara' with respect to a different tensor.-newtype Cotambara p a b = Cotambara { runCotambara :: forall c. p (Either a c) (Either b c) }--instance ProfunctorFunctor Cotambara where-  promap f (Cotambara p) = Cotambara (f p)--instance ProfunctorComonad Cotambara where-  proextract (Cotambara p)   = dimap Left (\(Left a) -> a) p-  produplicate (Cotambara p) = Cotambara (Cotambara $ dimap hither yon p) where-    hither :: Either (Either a b) c -> Either a (Either b c)-    hither (Left (Left x))   = Left x-    hither (Left (Right y))  = Right (Left y)-    hither (Right z)         = Right (Right z)--    yon    :: Either a (Either b c) -> Either (Either a b) c-    yon    (Left x)          = Left (Left x)-    yon    (Right (Left y))  = Left (Right y)-    yon    (Right (Right z)) = Right z--instance Profunctor p => Profunctor (Cotambara p) where-  dimap f g (Cotambara p) = Cotambara $ dimap (left f) (left g) p-  {-# INLINE dimap #-}--instance Profunctor p => Choice (Cotambara p) where-  left' = runCotambara . produplicate-  {-# INLINE left' #-}--instance Category p => Category (Cotambara p) where-  id = Cotambara id-  Cotambara p . Cotambara q = Cotambara (p . q)--instance Profunctor p => Functor (Cotambara p a) where-  fmap = rmap---- |--- @--- 'cotambara' '.' 'uncotambara' ≡ 'id'--- 'uncotambara' '.' 'cotambara' ≡ 'id'--- @-cotambara :: Choice p => (p :-> q) -> p :-> Cotambara q-cotambara f p = Cotambara $ f $ left' p---- |--- @--- 'cotambara' '.' 'uncotambara' ≡ 'id'--- 'uncotambara' '.' 'cotambara' ≡ 'id'--- @-uncotambara :: Profunctor q => (p :-> Cotambara q) -> p :-> q-uncotambara f p = dimap Left (\(Left a) -> a) $ runCotambara $ f p--------------------------------------------------------------------------------- * Copastro--------------------------------------------------------------------------------- | Copastro -| Cotambara-data Copastro p a b where-  Copastro :: (Either y z -> b) -> p x y -> (a -> Either x z) -> Copastro p a b--instance Profunctor p => Profunctor (Copastro p) where-  dimap f g (Copastro l m r) = Copastro (g . l) m (r . f)-  lmap f (Copastro l m r) = Copastro l m (r . f)-  rmap g (Copastro l m r) = Copastro (g . l) m r-  w #. Copastro l m r = Copastro (w #. l) m r-  Copastro l m r .# w = Copastro l m (r .# w)--instance ProfunctorAdjunction Copastro Cotambara where-  counit (Copastro f (Cotambara g) h) = dimap h f g-  unit p = Cotambara $ Copastro id p id--instance ProfunctorFunctor Copastro where-  promap f (Copastro l m r) = Copastro l (f m) r--instance ProfunctorMonad Copastro where-  proreturn p = Copastro (\(Left a)-> a) p Left-  projoin (Copastro l (Copastro m n o) q) = Copastro lm n oq where-    oq a = case q a of-      Left b -> case o b of-        Left c -> Left c-        Right z -> Right (Left z)-      Right z -> Right (Right z)-    lm (Left x) = l $ Left $ m $ Left x-    lm (Right (Left y)) = l $ Left $ m $ Right y-    lm (Right (Right z)) = l $ Right z
− src/Data/Profunctor/Trace.hs
@@ -1,19 +0,0 @@-{-# LANGUAGE GADTs #-}--------------------------------------------------------------------------------- |--- Module      :  Data.Profunctor.Trace--- Copyright   :  (C) 2011-2012 Edward Kmett--- License     :  BSD-style (see the file LICENSE)------ Maintainer  :  Edward Kmett <ekmett@gmail.com>--- Stability   :  provisional--- Portability :  GADTs---------------------------------------------------------------------------------module Data.Profunctor.Trace-  ( Trace(..)-  ) where---- | Coend of 'Data.Profunctor.Profunctor' from @Hask -> Hask@.-data Trace f where-  Trace :: f a a -> Trace f
+ src/Data/Profunctor/Traversing.hs view
@@ -0,0 +1,157 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE DeriveFunctor #-}+module Data.Profunctor.Traversing+  ( Traversing(..)+  , CofreeTraversing(..)+  , FreeTraversing(..)+  -- * Strong in terms of Traversing+  , firstTraversing+  , secondTraversing+  -- * Choice in terms of Traversing+  , leftTraversing+  , rightTraversing+  ) where++import Control.Applicative+import Control.Arrow (Kleisli(..))+import Data.Functor.Compose+import Data.Functor.Identity+import Data.Orphans ()+import Data.Profunctor.Choice+import Data.Profunctor.Monad+import Data.Profunctor.Strong+import Data.Profunctor.Types+import Data.Profunctor.Unsafe+import Data.Traversable+import Data.Tuple (swap)++#if __GLASGOW_HASKELL__ < 710+import Data.Foldable+import Prelude hiding (mapM)+#endif++firstTraversing :: Traversing p => p a b -> p (a, c) (b, c)+firstTraversing = dimap swap swap . traverse'++secondTraversing :: Traversing p => p a b -> p (c, a) (c, b)+secondTraversing = traverse'++swapE :: Either a b -> Either b a+swapE = either Right Left++leftTraversing :: Traversing p => p a b -> p (Either a c) (Either b c)+leftTraversing = dimap swapE swapE . traverse'++rightTraversing :: Traversing p => p a b -> p (Either c a) (Either c b)+rightTraversing = traverse'++newtype Bazaar a b t = Bazaar { runBazaar :: forall f. Applicative f => (a -> f b) -> f t }+  deriving Functor++instance Applicative (Bazaar a b) where+  pure a = Bazaar $ \_ -> pure a+  mf <*> ma = Bazaar $ \k -> runBazaar mf k <*> runBazaar ma k++instance Profunctor (Bazaar a) where+  dimap f g m = Bazaar $ \k -> g <$> runBazaar m (fmap f . k)++sell :: a -> Bazaar a b b+sell a = Bazaar $ \k -> k a++newtype Baz t b a = Baz { runBaz :: forall f. Applicative f => (a -> f b) -> f t }+  deriving Functor++-- bsell :: a -> Baz b b a+-- bsell a = Baz $ \k -> k a++-- aar :: Bazaar a b t -> Baz t b a+-- aar (Bazaar f) = Baz f++sold :: Baz t a a -> t+sold m = runIdentity (runBaz m Identity)++instance Foldable (Baz t b) where+  foldMap = foldMapDefault++instance Traversable (Baz t b) where+  traverse f bz = fmap (\m -> Baz (runBazaar m)) . getCompose . runBaz bz $ \x -> Compose $ sell <$> f x++instance Profunctor (Baz t) where+  dimap f g m = Baz $ \k -> runBaz m (fmap f . k . g)++-- | Note: Definitions in terms of 'wander' are much more efficient!+class (Choice p, Strong p) => Traversing p where+  traverse' :: Traversable f => p a b -> p (f a) (f b)+  traverse' = wander traverse++  wander :: (forall f. Applicative f => (a -> f b) -> s -> f t) -> p a b -> p s t+  wander f pab = dimap (\s -> Baz $ \afb -> f afb s) sold (traverse' pab)++#if __GLASGOW_HASKELL__ >= 706+  {-# MINIMAL wander | traverse' #-}+#endif++instance Traversing (->) where+  traverse' = fmap+  wander f ab = runIdentity #. f (Identity #. ab)++instance Monad m => Traversing (Kleisli m) where+  traverse' (Kleisli m) = Kleisli (mapM m)+  wander f (Kleisli amb) = Kleisli $ unwrapMonad #. f (WrapMonad #. amb)++instance Applicative m => Traversing (Star m) where+  traverse' (Star m) = Star (traverse m)+  wander f (Star amb) = Star (f amb)++newtype CofreeTraversing p a b = CofreeTraversing { runCofreeTraversing :: forall f. Traversable f => p (f a) (f b) }++instance Profunctor p => Profunctor (CofreeTraversing p) where+  lmap f (CofreeTraversing p) = CofreeTraversing (lmap (fmap f) p)+  rmap g (CofreeTraversing p) = CofreeTraversing (rmap (fmap g) p)+  dimap f g (CofreeTraversing p) = CofreeTraversing (dimap (fmap f) (fmap g) p)++instance Profunctor p => Strong (CofreeTraversing p) where+  second' = traverse'++instance Profunctor p => Choice (CofreeTraversing p) where+  right' = traverse'++instance Profunctor p => Traversing (CofreeTraversing p) where+  -- !@(#*&() Compose isn't representational in its second arg or we could use #. and .#+  traverse' (CofreeTraversing p) = CofreeTraversing (dimap Compose getCompose p)++instance ProfunctorFunctor CofreeTraversing where+  promap f (CofreeTraversing p) = CofreeTraversing (f p)++instance ProfunctorComonad CofreeTraversing where+  proextract (CofreeTraversing p) = runIdentity #. p .# Identity+  produplicate (CofreeTraversing p) = CofreeTraversing (CofreeTraversing (dimap Compose getCompose p))++-- | @FreeTraversing -| CofreeTraversing@+data FreeTraversing p a b where+  FreeTraversing :: Traversable f => (f y -> b) -> p x y -> (a -> f x) -> FreeTraversing p a b++instance Profunctor (FreeTraversing p) where+  lmap f (FreeTraversing l m r) = FreeTraversing l m (r . f)+  rmap g (FreeTraversing l m r) = FreeTraversing (g . l) m r+  dimap f g (FreeTraversing l m r) = FreeTraversing (g . l) m (r . f)+  g #. FreeTraversing l m r = FreeTraversing (g #. l) m r+  FreeTraversing l m r .# f = FreeTraversing l m (r .# f)++instance Strong (FreeTraversing p) where+  second' = traverse'++instance Choice (FreeTraversing p) where+  right' = traverse'++instance Traversing (FreeTraversing p) where+  traverse' (FreeTraversing l m r) = FreeTraversing (fmap l .# getCompose) m (Compose #. fmap r)++instance ProfunctorFunctor FreeTraversing where+  promap f (FreeTraversing l m r) = FreeTraversing l (f m) r++instance ProfunctorMonad FreeTraversing where+  proreturn p = FreeTraversing runIdentity p Identity+  projoin (FreeTraversing l (FreeTraversing l' m r') r) = FreeTraversing ((l . fmap l') .# getCompose) m (Compose #. (fmap r' . r))
+ src/Data/Profunctor/Types.hs view
@@ -0,0 +1,229 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}++#if __GLASGOW_HASKELL__ >= 704 && __GLASGOW_HASKELL__ < 708+{-# LANGUAGE Trustworthy #-}+#endif++-----------------------------------------------------------------------------+-- |+-- Copyright   :  (C) 2011-2015 Edward Kmett,+-- License     :  BSD-style (see the file LICENSE)+--+-- Maintainer  :  Edward Kmett <ekmett@gmail.com>+-- Stability   :  provisional+-- Portability :  portable+--+-- 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.Types+  ( Profunctor(dimap, lmap, rmap)+  , Star(..)+  , Costar(..)+  , WrappedArrow(..)+  , Forget(..)+#ifndef HLINT+  , (:->)+#endif+  ) where++import Control.Applicative hiding (WrappedArrow(..))+import Control.Arrow+import Control.Category+import Control.Comonad+import Control.Monad (MonadPlus(..))+import Data.Distributive+import Data.Foldable+import Data.Monoid hiding (Product)+import Data.Profunctor.Unsafe+import Data.Traversable+import Prelude hiding (id,(.),sequence)++#if __GLASGOW_HASKELL__ >= 708+import Data.Coerce+#else+import Unsafe.Coerce+#endif++infixr 0 :->+type p :-> q = forall a b. p a b -> q a b++------------------------------------------------------------------------------+-- Star+------------------------------------------------------------------------------++-- | Lift a 'Functor' into a 'Profunctor' (forwards).+newtype Star f d c = Star { runStar :: d -> f c }++instance Functor f => Profunctor (Star f) where+  dimap ab cd (Star bfc) = Star (fmap cd . bfc . ab)+  {-# INLINE dimap #-}+  lmap k (Star f) = Star (f . k)+  {-# INLINE lmap #-}+  rmap k (Star f) = Star (fmap k . f)+  {-# INLINE rmap #-}+  -- We cannot safely overload ( #. ) because we didn't write the 'Functor'.+#if __GLASGOW_HASKELL__ >= 708+  p .# _ = coerce p+#else+  p .# _ = unsafeCoerce p+#endif+  {-# INLINE ( .# ) #-}++instance Functor f => Functor (Star f a) where+  fmap = rmap+  {-# INLINE fmap #-}++instance Applicative f => Applicative (Star f a) where+  pure a = Star $ \_ -> pure a+  Star ff <*> Star fx = Star $ \a -> ff a <*> fx a+  Star ff  *> Star fx = Star $ \a -> ff a  *> fx a+  Star ff <*  Star fx = Star $ \a -> ff a <*  fx a++instance Alternative f => Alternative (Star f a) where+  empty = Star $ \_ -> empty+  Star f <|> Star g = Star $ \a -> f a <|> g a++instance Monad f => Monad (Star f a) where+#if __GLASGOW_HASKELL__ < 710+  return a = Star $ \_ -> return a+#endif+  Star m >>= f = Star $ \ e -> do+    a <- m e+    runStar (f a) e++instance MonadPlus f => MonadPlus (Star f a) where+  mzero = Star $ \_ -> mzero+  Star f `mplus` Star g = Star $ \a -> f a `mplus` g a++instance Distributive f => Distributive (Star f a) where+  distribute fs = Star $ \a -> collect (($ a) .# runStar) fs++------------------------------------------------------------------------------+-- Costar+------------------------------------------------------------------------------++-- | Lift a 'Functor' into a 'Profunctor' (backwards).+newtype Costar f d c = Costar { runCostar :: f d -> c }++instance Functor f => Profunctor (Costar f) where+  dimap ab cd (Costar fbc) = Costar (cd . fbc . fmap ab)+  {-# INLINE dimap #-}+  lmap k (Costar f) = Costar (f . fmap k)+  {-# INLINE lmap #-}+  rmap k (Costar f) = Costar (k . f)+  {-# INLINE rmap #-}+#if __GLASGOW_HASKELL__ >= 708+  ( #. ) _ = coerce (\x -> x :: b) :: forall a b. Coercible b a => a -> b+#else+  ( #. ) _ = unsafeCoerce+#endif+  {-# INLINE ( #. ) #-}+  -- We cannot overload ( .# ) because we didn't write the 'Functor'.++instance Distributive (Costar f d) where+  distribute fs = Costar $ \gd -> fmap (($ gd) .# runCostar) fs++instance Functor (Costar f a) where+  fmap k (Costar f) = Costar (k . f)+  {-# INLINE fmap #-}+  a <$ _ = Costar $ \_ -> a+  {-# INLINE (<$) #-}++instance Applicative (Costar f a) where+  pure a = Costar $ \_ -> a+  Costar ff <*> Costar fx = Costar $ \a -> ff a (fx a)+  _ *> m = m+  m <* _ = m++instance Monad (Costar f a) where+  return = pure+  Costar m >>= f = Costar $ \ x -> runCostar (f (m x)) x++------------------------------------------------------------------------------+-- Wrapped Profunctors+------------------------------------------------------------------------------++-- | Wrap an arrow for use as a 'Profunctor'.+newtype WrappedArrow p a b = WrapArrow { unwrapArrow :: p a b }++instance Category p => Category (WrappedArrow p) where+  WrapArrow f . WrapArrow g = WrapArrow (f . g)+  {-# INLINE (.) #-}+  id = WrapArrow id+  {-# INLINE id #-}++instance Arrow p => Arrow (WrappedArrow p) where+  arr = WrapArrow . arr+  {-# INLINE arr #-}+  first = WrapArrow . first . unwrapArrow+  {-# INLINE first #-}+  second = WrapArrow . second . unwrapArrow+  {-# INLINE second #-}+  WrapArrow a *** WrapArrow b = WrapArrow (a *** b)+  {-# INLINE (***) #-}+  WrapArrow a &&& WrapArrow b = WrapArrow (a &&& b)+  {-# INLINE (&&&) #-}++instance ArrowZero p => ArrowZero (WrappedArrow p) where+  zeroArrow = WrapArrow zeroArrow+  {-# INLINE zeroArrow #-}++instance ArrowChoice p => ArrowChoice (WrappedArrow p) where+  left = WrapArrow . left . unwrapArrow+  {-# INLINE left #-}+  right = WrapArrow . right . unwrapArrow+  {-# INLINE right #-}+  WrapArrow a +++ WrapArrow b = WrapArrow (a +++ b)+  {-# INLINE (+++) #-}+  WrapArrow a ||| WrapArrow b = WrapArrow (a ||| b)+  {-# INLINE (|||) #-}++instance ArrowApply p => ArrowApply (WrappedArrow p) where+  app = WrapArrow $ app . arr (first unwrapArrow)+  {-# INLINE app #-}++instance ArrowLoop p => ArrowLoop (WrappedArrow p) where+  loop = WrapArrow . loop . unwrapArrow+  {-# INLINE loop #-}++instance Arrow p => Profunctor (WrappedArrow p) where+  lmap = (^>>)+  {-# INLINE lmap #-}+  rmap = (^<<)+  {-# INLINE rmap #-}+  -- We cannot safely overload ( #. ) or ( .# ) because we didn't write the 'Arrow'.++------------------------------------------------------------------------------+-- Forget+------------------------------------------------------------------------------++newtype Forget r a b = Forget { runForget :: a -> r }++instance Profunctor (Forget r) where+  dimap f _ (Forget k) = Forget (k . f)+  {-# INLINE dimap #-}+  lmap f (Forget k) = Forget (k . f)+  {-# INLINE lmap #-}+  rmap _ (Forget k) = Forget k+  {-# INLINE rmap #-}++instance Functor (Forget r a) where+  fmap _ (Forget k) = Forget k+  {-# INLINE fmap #-}++instance Foldable (Forget r a) where+  foldMap _ _ = mempty+  {-# INLINE foldMap #-}++instance Traversable (Forget r a) where+  traverse _ (Forget k) = pure (Forget k)+  {-# INLINE traverse #-}
src/Data/Profunctor/Unsafe.hs view
@@ -7,7 +7,7 @@ {-# LANGUAGE ScopedTypeVariables #-} ----------------------------------------------------------------------------- -- |--- Copyright   :  (C) 2011-2013 Edward Kmett+-- Copyright   :  (C) 2011-2015 Edward Kmett -- License     :  BSD-style (see the file LICENSE) -- -- Maintainer  :  Edward Kmett <ekmett@gmail.com>@@ -38,8 +38,14 @@ import Control.Category import Control.Comonad (Cokleisli(..)) import Control.Monad (liftM)+import Data.Bifunctor.Biff (Biff(..)) import Data.Bifunctor.Clown (Clown(..)) import Data.Bifunctor.Joker (Joker(..))+import Data.Bifunctor.Product (Product(..))+import Data.Bifunctor.Tannen (Tannen(..))+#if __GLASGOW_HASKELL__ < 710+import Data.Functor+#endif import Data.Functor.Contravariant (Contravariant(..)) import Data.Tagged import Prelude hiding (id,(.),sequence)@@ -258,3 +264,32 @@   {-# INLINE rmap #-}   dimap _ g (Joker fb) = Joker (fmap g fb)   {-# INLINE dimap #-}++instance (Profunctor p, Functor f, Functor g) => Profunctor (Biff p f g) where+  lmap f (Biff p) = Biff (lmap (fmap f) p)+  rmap g (Biff p) = Biff (rmap (fmap g) p)+  dimap f g (Biff p) = Biff (dimap (fmap f) (fmap g) p)++instance (Profunctor p, Profunctor q) => Profunctor (Product p q) where+  lmap  f   (Pair p q) = Pair (lmap f p) (lmap f q)+  {-# INLINE lmap #-}+  rmap    g (Pair p q) = Pair (rmap g p) (rmap g q)+  {-# INLINE rmap #-}+  dimap f g (Pair p q) = Pair (dimap f g p) (dimap f g q)+  {-# INLINE dimap #-}+  ( #. ) f (Pair p q) = Pair (f #. p) (f #. q)+  {-# INLINE ( #. ) #-}+  ( .# ) (Pair p q) f = Pair (p .# f) (q .# f)+  {-# INLINE ( .# ) #-}++instance (Functor f, Profunctor p) => Profunctor (Tannen f p) where+  lmap f (Tannen h) = Tannen (lmap f <$> h)+  {-# INLINE lmap #-}+  rmap g (Tannen h) = Tannen (rmap g <$> h)+  {-# INLINE rmap #-}+  dimap f g (Tannen h) = Tannen (dimap f g <$> h)+  {-# INLINE dimap #-}+  ( #. ) f (Tannen h) = Tannen ((f #.) <$> h)+  {-# INLINE ( #. ) #-}+  ( .# ) (Tannen h) f = Tannen ((.# f) <$> h)+  {-# INLINE ( .# ) #-}