packages feed

profunctors 4.0.4 → 4.1

raw patch · 14 files changed

+759/−170 lines, 14 filesdep +distributivedep ~base

Dependencies added: distributive

Dependency ranges changed: base

Files

CHANGELOG.markdown view
@@ -1,3 +1,14 @@+4.1+---+* Flipped the order of 'Procompose'+* Added the notion of Monads and Comonads on the category of profunctors.+* Added 'Cayley' which takes normal Haskell Monads and Comonads to a 'ProfunctorMonad' and 'ProfunctorComonad' respectively. Cayley is also known as the 'static arrow' construction+* Added 'Closed' which is adjoint to 'Strong'.+* Added 'Closure' which freely adjoins 'Closed' to any 'Profunctor'.+* Added 'Tambara' which freely adjoins 'Strong' to any 'Profunctor'.+* Added 'Cotambara' which freely adjoins 'Choice' to any 'Profunctor'.+* Under the new 'Procompose' the old 'Rift' is now 'Ran', and the old 'Lift' was misnamed. It is now 'Rift'+ 4.0.3 ----- * Added `Data.Profunctor.Lift` containing the left Kan lift of a profunctor.
profunctors.cabal view
@@ -1,6 +1,6 @@ name:          profunctors category:      Control, Categories-version:       4.0.4+version:       4.1 license:       BSD3 cabal-version: >= 1.10 license-file:  LICENSE@@ -29,17 +29,23 @@   build-depends:     base                >= 4     && < 5,     comonad             >= 4     && < 5,+    distributive        >= 0.4.4 && < 1,     semigroupoids       >= 4     && < 5,     tagged              >= 0.4.4 && < 1,     transformers        >= 0.2   && < 0.5    exposed-modules:     Data.Profunctor+    Data.Profunctor.Adjunction+    Data.Profunctor.Cayley+    Data.Profunctor.Closed+    Data.Profunctor.Codensity     Data.Profunctor.Composition     Data.Profunctor.Collage-    Data.Profunctor.Lift+    Data.Profunctor.Monad+    Data.Profunctor.Ran     Data.Profunctor.Rep-    Data.Profunctor.Rift+    Data.Profunctor.Tambara     Data.Profunctor.Trace     Data.Profunctor.Unsafe 
src/Data/Profunctor.hs view
@@ -1,4 +1,6 @@ {-# LANGUAGE CPP #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE RankNTypes #-} #if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Trustworthy #-} #endif@@ -31,6 +33,9 @@   , DownStar(..)   , WrappedArrow(..)   , Forget(..)+#ifndef HLINT+  , type (-/->)+#endif   ) where  import Control.Applicative hiding (WrappedArrow(..))@@ -45,6 +50,8 @@ import Data.Profunctor.Unsafe import Prelude hiding (id,(.),sequence) import Unsafe.Coerce++type p -/-> q = forall a b. p a b -> q a b  ------------------------------------------------------------------------------ -- UpStar
+ src/Data/Profunctor/Adjunction.hs view
@@ -0,0 +1,11 @@+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE RankNTypes #-}+module Data.Profunctor.Adjunction where++import Data.Profunctor++class f -| u | f -> u, u -> f where+  unit   :: Profunctor p => p -/-> u (f p)+  counit :: Profunctor p => f (u p) -/-> p
+ src/Data/Profunctor/Cayley.hs view
@@ -0,0 +1,79 @@+{-# LANGUAGE CPP #-}+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702+{-# LANGUAGE Trustworthy #-}+#endif+-----------------------------------------------------------------------------+-- |+-- Copyright   :  (C) 2014 Edward Kmett+-- License     :  BSD-style (see the file LICENSE)+--+-- Maintainer  :  Edward Kmett <ekmett@gmail.com>+-- Stability   :  experimental+-- Portability :  portable+--+----------------------------------------------------------------------------++module Data.Profunctor.Cayley where++import Control.Applicative+import Control.Arrow+import Control.Category+import Control.Comonad+import Data.Profunctor+import Data.Profunctor.Monad+import Data.Profunctor.Unsafe+import Prelude hiding ((.), id)++-- static arrows+newtype Cayley f p a b = Cayley { runCayley :: f (p a b) }++-- | Cayley transforms Monads in @Hask@ into monads on @Prof@+instance Monad f => ProfunctorMonad (Cayley f) where+  proreturn = Cayley . return+  projoin (Cayley m) = Cayley $ m >>= runCayley++-- | Cayley transforms Comonads in @Hask@ into comonads on @Prof@+instance Comonad f => ProfunctorComonad (Cayley f) where+  proextract = extract . runCayley+  produplicate (Cayley w) = Cayley $ extend Cayley w++instance (Functor f, Profunctor p) => Profunctor (Cayley f p) where+  dimap f g = Cayley . fmap (dimap f g) . runCayley+  lmap f = Cayley . fmap (lmap f) . runCayley+  rmap g = Cayley . fmap (rmap g) . runCayley+  w #. Cayley fp = Cayley $ fmap (w #.) fp+  Cayley fp .# w = Cayley $ fmap (.# w) fp++instance (Functor f, Strong p) => Strong (Cayley f p) where+  first'  = Cayley . fmap first' . runCayley+  second' = Cayley . fmap second' . runCayley++instance (Functor f, Choice p) => Choice (Cayley f p) where+  left'   = Cayley . fmap left' . runCayley+  right'  = Cayley . fmap right' . runCayley++instance (Applicative f, Category p) => Category (Cayley f p) where+  id = Cayley $ pure id+  Cayley fpbc . Cayley fpab = Cayley $ liftA2 (.) fpbc fpab++instance (Applicative f, Arrow p) => Arrow (Cayley f p) where+  arr f = Cayley $ pure $ arr f+  first = Cayley . fmap first . runCayley+  second = Cayley . fmap second . runCayley+  Cayley ab *** Cayley cd = Cayley $ liftA2 (***) ab cd+  Cayley ab &&& Cayley ac = Cayley $ liftA2 (&&&) ab ac++instance (Applicative f, ArrowChoice p) => ArrowChoice (Cayley f p) where+  left  = Cayley . fmap left . runCayley+  right = Cayley . fmap right . runCayley+  Cayley ab +++ Cayley cd = Cayley $ liftA2 (+++) ab cd+  Cayley ac ||| Cayley bc = Cayley $ liftA2 (|||) ac bc+  +instance (Applicative f, ArrowLoop p) => ArrowLoop (Cayley f p) where+  loop = Cayley . fmap loop . runCayley++instance (Applicative f, ArrowZero p) => ArrowZero (Cayley f p) where+  zeroArrow = Cayley $ pure zeroArrow++instance (Applicative f, ArrowPlus p) => ArrowPlus (Cayley f p) where+  Cayley f <+> Cayley g = Cayley (liftA2 (<+>) f g)
+ src/Data/Profunctor/Closed.hs view
@@ -0,0 +1,165 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE MultiParamTypeClasses #-}+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702+{-# LANGUAGE Trustworthy #-}+#endif++module Data.Profunctor.Closed+  ( Closed(..)+  , Closure(..)+  , close+  , unclose+  , Environment(..)+  ) where++import Control.Applicative+import Control.Arrow+import Control.Category+import Control.Comonad+import Data.Distributive+import Data.Monoid+import Data.Profunctor+import Data.Profunctor.Adjunction+import Data.Profunctor.Monad+import Data.Profunctor.Unsafe+import Data.Tagged+import Prelude hiding ((.),id)++--------------------------------------------------------------------------------+-- * Closed+--------------------------------------------------------------------------------++-- | A strong profunctor allows the monoidal structure to pass through.+--+-- A closed profunctor allows the closed structure to pass through.+class Profunctor p => Closed p where+  closed :: p a b -> p (x -> a) (x -> b)++instance Closed Tagged where+  closed (Tagged b) = Tagged (const b)++instance Closed (->) where+  closed = (.)++instance Functor f => Closed (DownStar f) where+  closed (DownStar fab) = DownStar $ \fxa x -> fab (fmap ($x) fxa)++instance Functor f => Closed (Cokleisli f) where+  closed (Cokleisli fab) = Cokleisli $ \fxa x -> fab (fmap ($x) fxa)++instance Distributive f => Closed (UpStar f) where+  closed (UpStar afb) = UpStar $ \xa -> distribute $ \x -> afb (xa x)++instance (Distributive f, Monad f) => Closed (Kleisli f) where+  closed (Kleisli afb) = Kleisli $ \xa -> distribute $ \x -> afb (xa x)++instance Monoid r => Closed (Forget r) where+  closed _ = Forget $ \_ -> mempty++--------------------------------------------------------------------------------+-- * Closure+--------------------------------------------------------------------------------++-- | 'Closure' adjoins a 'Closed' structure to any 'Profunctor'.+--+-- Analogous to 'Data.Profunctor.Tambara.Tambara' for 'Closed'.++newtype Closure p a b = Closure { runClosure :: forall x. p (x -> a) (x -> b) }++instance Profunctor p => Profunctor (Closure p) where+  dimap f g (Closure p) = Closure $ dimap (fmap f) (fmap g) p+  lmap f (Closure p) = Closure $ lmap (fmap f) p+  rmap f (Closure p) = Closure $ rmap (fmap f) p+  w #. Closure p = Closure $ fmap w #. p+  Closure p .# w = Closure $ p .# fmap w++instance ProfunctorComonad Closure where+  proextract = dimap const ($ ()) . runClosure+  produplicate (Closure p) = Closure $ Closure $ dimap uncurry curry p++instance Profunctor p => Closed (Closure p) where+  closed = runClosure . produplicate++instance Strong p => Strong (Closure p) where+  first' (Closure p) = Closure $ dimap hither yon $ first' p++instance Category p => Category (Closure p) where+  id = Closure id+  Closure p . Closure q = Closure (p . q)++hither :: (s -> (a,b)) -> (s -> a, s -> b)+hither h = (fst . h, snd . h)++yon :: (s -> a, s -> b) -> s -> (a,b)+yon h s = (fst h s, snd h s)++instance Arrow p => Arrow (Closure p) where+  arr f = Closure (arr (f .))+  first (Closure f) = Closure $ arr yon . first f . arr hither++instance ArrowLoop p => ArrowLoop (Closure p) where+  loop (Closure f) = Closure $ loop (arr hither . f . arr yon)++instance ArrowZero p => ArrowZero (Closure p) where+  zeroArrow = Closure zeroArrow++instance ArrowPlus p => ArrowPlus (Closure p) where+  Closure f <+> Closure g = Closure (f <+> g)++instance Profunctor p => Functor (Closure p a) where+  fmap = rmap++instance (Profunctor p, Arrow p) => Applicative (Closure p a) where+  pure x = arr (const x)+  f <*> g = arr (uncurry id) . (f &&& g)++instance (Profunctor p, ArrowPlus p) => Alternative (Closure p a) where+  empty = zeroArrow+  f <|> g = f <+> g++instance (Profunctor p, Arrow p, Monoid b) => Monoid (Closure p a b) where+  mempty = pure mempty+  mappend = liftA2 mappend++-- |+-- @+-- 'close' '.' 'unclose' ≡ 'id'+-- 'unclose' '.' 'close' ≡ 'id'+-- @+close :: Closed p => (p -/-> q) -> p -/-> Closure q+close f p = Closure $ f $ closed p++-- |+-- @+-- 'close' '.' 'unclose' ≡ 'id'+-- 'unclose' '.' 'close' ≡ 'id'+-- @+unclose :: Profunctor q => (p -/-> Closure q) -> p -/-> q+unclose f p = dimap const ($ ()) $ runClosure $ f p++--------------------------------------------------------------------------------+-- * Environment+--------------------------------------------------------------------------------++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+  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+  w #. Environment l m r = Environment (w #. l) m r+  Environment l m r .# w = Environment l m (r .# w)++instance ProfunctorMonad Environment where+  proreturn p = Environment ($ ()) p const+  projoin (Environment l (Environment m n o) p) = Environment (lm . curry) n op where+    op a (b, c) = o (p a b) c+    lm zr = l (m.zr)++instance Environment -| Closure where+  counit (Environment g (Closure p) f) = dimap f g p+  unit p = Closure (Environment id p id)
+ src/Data/Profunctor/Codensity.hs view
@@ -0,0 +1,54 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE TypeFamilies #-}+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702+{-# 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
@@ -2,18 +2,20 @@ {-# LANGUAGE GADTs #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE MultiParamTypeClasses #-} #if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Trustworthy #-} #endif ----------------------------------------------------------------------------- -- | -- Module      :  Data.Profunctor.Composition--- Copyright   :  (C) 2011-2012 Edward Kmett+-- Copyright   :  (C) 2014 Edward Kmett -- License     :  BSD-style (see the file LICENSE) -- -- Maintainer  :  Edward Kmett <ekmett@gmail.com>--- Stability   :  provisional--- Portability :  GADTs+-- Stability   :  experimental+-- Portability :  GADTs, TFs, MPTCs, RankN -- ---------------------------------------------------------------------------- module Data.Profunctor.Composition@@ -21,13 +23,16 @@   -- * Profunctor Composition     Procompose(..)   , procomposed-  -- * Bicategorical Associators+  -- * Unitors and Associator   , idl   , idr   , assoc   -- * Generalized Composition   , upstars, kleislis   , downstars, cokleislis+  -- * Right Kan Lift+  , Rift(..)+  , decomposeRift   ) where  import Control.Arrow@@ -36,6 +41,9 @@ import Control.Monad (liftM) 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.Unsafe import Prelude hiding ((.),id)@@ -52,43 +60,46 @@ -- -- <http://blog.sigfpe.com/2011/07/profunctors-in-haskell.html> data Procompose p q d c where-  Procompose :: p d a -> q a c -> Procompose p q d c+  Procompose :: p x c -> q d x -> Procompose p q d c +instance Category p => ProfunctorMonad (Procompose p) where+  proreturn = Procompose id+  projoin (Procompose p (Procompose q r)) = Procompose (p . q) r+ procomposed :: Category p => Procompose p p a b -> p a b-procomposed (Procompose pda pac) = pac . pda+procomposed (Procompose pxc pdx) = pxc . pdx {-# INLINE procomposed #-} - instance (Profunctor p, Profunctor q) => Profunctor (Procompose p q) where-  dimap l r (Procompose f g) = Procompose (lmap l f) (rmap r g)+  dimap l r (Procompose f g) = Procompose (rmap r f) (lmap l g)   {-# INLINE dimap #-}-  lmap k (Procompose f g) = Procompose (lmap k f) g+  lmap k (Procompose f g) = Procompose f (lmap k g)   {-# INLINE rmap #-}-  rmap k (Procompose f g) = Procompose f (rmap k g)+  rmap k (Procompose f g) = Procompose (rmap k f) g   {-# INLINE lmap #-}-  k #. Procompose f g     = Procompose f (k #. g)+  k #. Procompose f g     = Procompose (k #. f) g   {-# INLINE ( #. ) #-}-  Procompose f g .# k     = Procompose (f .# k) g+  Procompose f g .# k     = Procompose f (g .# k)   {-# INLINE ( .# ) #-} -instance Profunctor q => Functor (Procompose p q a) where-  fmap k (Procompose f g) = Procompose f (rmap k g)+instance Profunctor p => Functor (Procompose p q a) where+  fmap k (Procompose f g) = Procompose (rmap k f) g   {-# INLINE fmap #-}  -- | The composition of two 'Representable' 'Profunctor's is 'Representable' by -- the composition of their representations. instance (Representable p, Representable q) => Representable (Procompose p q) where-  type Rep (Procompose p q) = Compose (Rep p) (Rep q)-  tabulate f = Procompose (tabulate (getCompose . f)) (tabulate id)+  type Rep (Procompose p q) = Compose (Rep q) (Rep p)+  tabulate f = Procompose (tabulate id) (tabulate (getCompose . f))   {-# INLINE tabulate #-}-  rep (Procompose f g) d = Compose $ rep g <$> rep f d+  rep (Procompose g f) d = Compose $ rep g <$> rep f d   {-# INLINE rep #-}  instance (Corepresentable p, Corepresentable q) => Corepresentable (Procompose p q) where-  type Corep (Procompose p q) = Compose (Corep q) (Corep p)-  cotabulate f = Procompose (cotabulate id) (cotabulate (f . Compose))+  type Corep (Procompose p q) = Compose (Corep p) (Corep q)+  cotabulate f = Procompose (cotabulate (f . Compose)) (cotabulate id)   {-# INLINE cotabulate #-}-  corep (Procompose f g) (Compose d) = corep g $ corep f <$> d+  corep (Procompose g f) (Compose d) = corep g $ corep f <$> d   {-# INLINE corep #-}  instance (Strong p, Strong q) => Strong (Procompose p q) where@@ -103,6 +114,9 @@   right' (Procompose x y) = Procompose (right' x) (right' y)   {-# INLINE right' #-} +instance (Closed p, Closed q) => Closed (Procompose p q) where+  closed (Procompose x y) = Procompose (closed x) (closed y)+  {-# INLINE closed #-}  -- * Lax identity @@ -116,7 +130,7 @@ -- 'idl' :: 'Profunctor' q => Iso' ('Procompose' (->) q d c) (q d c) -- @ idl :: Profunctor q => Iso (Procompose (->) q d c) (Procompose (->) r d' c') (q d c) (r d' c')-idl = dimap (\(Procompose f g) -> lmap f g) (fmap (Procompose id))+idl = dimap (\(Procompose g f) -> rmap g f) (fmap (Procompose id))  -- | @(->)@ functions as a lax identity for 'Profunctor' composition. --@@ -128,7 +142,7 @@ -- 'idr' :: 'Profunctor' q => Iso' ('Procompose' q (->) d c) (q d c) -- @ idr :: Profunctor q => Iso (Procompose q (->) d c) (Procompose r (->) d' c') (q d c) (r d' c')-idr = dimap (\(Procompose f g) -> rmap g f) (fmap (`Procompose` id))+idr = dimap (\(Procompose g f) -> lmap f g) (fmap (`Procompose` id))   -- | The associator for 'Profunctor' composition.@@ -148,14 +162,14 @@ -- isomorphic to @a -> f (g c)@. -- -- @'upstars' :: 'Functor' f => Iso' ('Procompose' ('UpStar' f) ('UpStar' g) d c) ('UpStar' ('Compose' f g) d c)@-upstars :: Functor f+upstars :: Functor g         => Iso (Procompose (UpStar f ) (UpStar g ) d  c )                (Procompose (UpStar f') (UpStar g') d' c')-               (UpStar (Compose f  g ) d  c )-               (UpStar (Compose f' g') d' c')+               (UpStar (Compose g  f ) d  c )+               (UpStar (Compose g' f') d' c') upstars = dimap hither (fmap yon) where-  hither (Procompose (UpStar dfx) (UpStar xgc)) = UpStar (Compose . fmap xgc . dfx)-  yon (UpStar dfgc) = Procompose (UpStar (getCompose . dfgc)) (UpStar id)+  hither (Procompose (UpStar xgc) (UpStar dfx)) = UpStar (Compose . fmap xgc . dfx)+  yon (UpStar dfgc) = Procompose (UpStar id) (UpStar (getCompose . dfgc))  -- | 'Profunctor' composition generalizes 'Functor' composition in two ways. --@@ -163,36 +177,80 @@ -- isomorphic to @g (f a) -> c@. -- -- @'downstars' :: 'Functor' f => Iso' ('Procompose' ('DownStar' f) ('DownStar' g) d c) ('DownStar' ('Compose' g f) d c)@-downstars :: Functor g+downstars :: Functor f           => Iso (Procompose (DownStar f ) (DownStar g ) d  c )                  (Procompose (DownStar f') (DownStar g') d' c')-                 (DownStar (Compose g  f ) d  c )-                 (DownStar (Compose g' f') d' c')+                 (DownStar (Compose f  g ) d  c )+                 (DownStar (Compose f' g') d' c') downstars = dimap hither (fmap yon) where-  hither (Procompose (DownStar fdx) (DownStar gxc)) = DownStar (gxc . fmap fdx . getCompose)-  yon (DownStar dgfc) = Procompose (DownStar id) (DownStar (dgfc . Compose))+  hither (Procompose (DownStar gxc) (DownStar fdx)) = DownStar (gxc . fmap fdx . getCompose)+  yon (DownStar dgfc) = Procompose (DownStar (dgfc . Compose)) (DownStar id)  -- | This is a variant on 'upstars' that uses 'Kleisli' instead of 'UpStar'. -- -- @'kleislis' :: 'Monad' f => Iso' ('Procompose' ('Kleisli' f) ('Kleisli' g) d c) ('Kleisli' ('Compose' f g) d c)@-kleislis :: Monad f+kleislis :: Monad g         => Iso (Procompose (Kleisli f ) (Kleisli g ) d  c )                (Procompose (Kleisli f') (Kleisli g') d' c')-               (Kleisli (Compose f  g ) d  c )-               (Kleisli (Compose f' g') d' c')+               (Kleisli (Compose g  f ) d  c )+               (Kleisli (Compose g' f') d' c') kleislis = dimap hither (fmap yon) where-  hither (Procompose (Kleisli dfx) (Kleisli xgc)) = Kleisli (Compose . liftM xgc . dfx)-  yon (Kleisli dfgc) = Procompose (Kleisli (getCompose . dfgc)) (Kleisli id)+  hither (Procompose (Kleisli xgc) (Kleisli dfx)) = Kleisli (Compose . liftM xgc . dfx)+  yon (Kleisli dfgc) = Procompose (Kleisli id) (Kleisli (getCompose . dfgc))  -- | This is a variant on 'downstars' that uses 'Cokleisli' instead -- of 'DownStar'. -- -- @'cokleislis' :: 'Functor' f => Iso' ('Procompose' ('Cokleisli' f) ('Cokleisli' g) d c) ('Cokleisli' ('Compose' g f) d c)@-cokleislis :: Functor g+cokleislis :: Functor f           => Iso (Procompose (Cokleisli f ) (Cokleisli g ) d  c )                  (Procompose (Cokleisli f') (Cokleisli g') d' c')-                 (Cokleisli (Compose g  f ) d  c )-                 (Cokleisli (Compose g' f') d' c')+                 (Cokleisli (Compose f  g ) d  c )+                 (Cokleisli (Compose f' g') d' c') cokleislis = dimap hither (fmap yon) where-  hither (Procompose (Cokleisli fdx) (Cokleisli gxc)) = Cokleisli (gxc . fmap fdx . getCompose)-  yon (Cokleisli dgfc) = Procompose (Cokleisli id) (Cokleisli (dgfc . Compose))+  hither (Procompose (Cokleisli gxc) (Cokleisli fdx)) = Cokleisli (gxc . fmap fdx . getCompose)+  yon (Cokleisli dgfc) = Procompose (Cokleisli (dgfc . Compose)) (Cokleisli id)++----------------------------------------------------------------------------+-- * 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 }++instance Category p => ProfunctorComonad (Rift p) where+  proextract (Rift f) = f id+  produplicate (Rift f) = Rift $ \p -> Rift $ \q -> f (q . p)++instance (Profunctor p, Profunctor q) => Profunctor (Rift p q) where+  dimap ca bd f = Rift (lmap ca . runRift f . lmap bd)+  {-# INLINE dimap #-}+  lmap ca f = Rift (lmap ca . runRift f)+  {-# INLINE lmap #-}+  rmap bd f = Rift (runRift f . lmap bd)+  {-# INLINE rmap #-}+  bd #. f = Rift (\p -> runRift f (p .# bd))+  {-# INLINE ( #. ) #-}+  f .# ca = Rift (\p -> runRift f p .# ca)+  {-# INLINE (.#) #-}++instance Profunctor p => Functor (Rift p q a) where+  fmap bd f = Rift (runRift f . lmap bd)+  {-# INLINE fmap #-}++-- | @'Rift' p p@ forms a 'Monad' in the 'Profunctor' 2-category, which is isomorphic to a Haskell 'Category' instance.+instance p ~ q => Category (Rift p q) where+  id = Rift id+  {-# INLINE id #-}+  Rift f . Rift g = Rift (g . f)+  {-# INLINE (.) #-}++-- | The 2-morphism that defines a left Kan lift.+--+-- Note: When @p@ is right adjoint to @'Rift' p (->)@ then 'decomposeRift' is the 'counit' of the adjunction.+decomposeRift :: Procompose p (Rift p q) -/-> q+decomposeRift (Procompose p (Rift pq)) = pq p+{-# INLINE decomposeRift #-}++instance Procompose p -| Rift p where+  counit (Procompose p (Rift pq)) = pq p+  unit q = Rift $ \p -> Procompose p q
− src/Data/Profunctor/Lift.hs
@@ -1,59 +0,0 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE Rank2Types #-}-{-# LANGUAGE TypeFamilies #-}-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702-{-# 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.Lift-  ( Lift(..)-  , decomposeLift-  ) where--import Control.Category-import Data.Profunctor.Unsafe-import Data.Profunctor.Composition-import Prelude hiding (id,(.))---- | This represents the left 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 Lift p q a b = Lift { runLift :: forall x. p b x -> q a x }---instance (Profunctor p, Profunctor q) => Profunctor (Lift p q) where-  dimap ca bd f = Lift (lmap ca . runLift f . lmap bd)-  {-# INLINE dimap #-}-  lmap ca f = Lift (lmap ca . runLift f)-  {-# INLINE lmap #-}-  rmap bd f = Lift (runLift f . lmap bd)-  {-# INLINE rmap #-}-  bd #. f = Lift (\p -> runLift f (p .# bd))-  {-# INLINE ( #. ) #-}-  f .# ca = Lift (\p -> runLift f p .# ca)-  {-# INLINE (.#) #-}--instance Profunctor p => Functor (Lift p q a) where-  fmap bd f = Lift (runLift f . lmap bd)-  {-# INLINE fmap #-}---- | @'Lift' p p@ forms a 'Monad' in the 'Profunctor' 2-category, which is isomorphic to a Haskell 'Category' instance.-instance p ~ q => Category (Lift p q) where-  id = Lift id-  {-# INLINE id #-}-  Lift f . Lift g = Lift (g . f)-  {-# INLINE (.) #-}---- | The 2-morphism that defines a left Kan lift.------ Note: When @p@ is right adjoint to @'Lift' p (->)@ then 'decomposeLift' is the 'counit' of the adjunction.-decomposeLift :: Procompose (Lift p q) p a b -> q a b-decomposeLift (Procompose (Lift pq) p) = pq p-{-# INLINE decomposeLift #-}
+ src/Data/Profunctor/Monad.hs view
@@ -0,0 +1,13 @@+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeOperators #-}+module Data.Profunctor.Monad where++import Data.Profunctor++class ProfunctorMonad t where+  proreturn :: Profunctor p => p -/-> t p+  projoin   :: Profunctor p => t (t p) -/-> t p++class ProfunctorComonad t where+  proextract :: Profunctor p => t p -/-> p+  produplicate :: Profunctor p => t p -/-> t (t p)
+ src/Data/Profunctor/Ran.hs view
@@ -0,0 +1,80 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702+{-# LANGUAGE Trustworthy #-}+#endif+-----------------------------------------------------------------------------+-- |+-- Copyright   :  (C) 2013-2014 Edward Kmett and Dan Doel+-- License     :  BSD-style (see the file LICENSE)+--+-- Maintainer  :  Edward Kmett <ekmett@gmail.com>+-- Stability   :  provisional+-- Portability :  Rank2Types, TFs+--+----------------------------------------------------------------------------+module Data.Profunctor.Ran+  ( Ran(..)+  , decomposeRan+  , precomposeRan+  , curryRan+  , uncurryRan+  ) where++import Control.Category+import Data.Profunctor+import Data.Profunctor.Composition+import Data.Profunctor.Monad+import Data.Profunctor.Unsafe+import Prelude hiding (id,(.))++-- | 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 }++instance Category p => ProfunctorComonad (Ran p) where+  proextract (Ran f) = f id+  produplicate (Ran f) = Ran $ \ p -> Ran $ \q -> f (p . q)++instance (Profunctor p, Profunctor q) => Profunctor (Ran p q) where+  dimap ca bd f = Ran (rmap bd . runRan f . rmap ca)+  {-# INLINE dimap #-}+  lmap ca f = Ran (runRan f . rmap ca)+  {-# INLINE lmap #-}+  rmap bd f = Ran (rmap bd . runRan f)+  {-# INLINE rmap #-}+  bd #. f = Ran (\p -> bd #. runRan f p)+  {-# INLINE ( #. ) #-}+  f .# ca = Ran (\p -> runRan f (ca #. p))+  {-# INLINE (.#) #-}++instance Profunctor q => Functor (Ran p q a) where+  fmap bd f = Ran (rmap bd . runRan f)+  {-# INLINE fmap #-}++-- | @'Ran' p p@ forms a 'Monad' in the 'Profunctor' 2-category, which is isomorphic to a Haskell 'Category' instance.+instance p ~ q => Category (Ran p q) where+  id = Ran id+  {-# INLINE id #-}+  Ran f . Ran g = Ran (f . g)+  {-# INLINE (.) #-}++-- | The 2-morphism that defines a right Kan extension.+--+-- Note: When @q@ is left adjoint to @'Ran' q (->)@ then 'decomposeRan' is the 'counit' of the adjunction.+decomposeRan :: Procompose (Ran q p) q -/-> p+decomposeRan (Procompose (Ran qp) q) = qp q+{-# INLINE decomposeRan #-}++precomposeRan :: Profunctor q => Procompose q (Ran p (->)) -/-> Ran p q+precomposeRan (Procompose p pf) = Ran (\pxa -> runRan pf pxa `lmap` p)+{-# INLINE precomposeRan #-}++curryRan :: (Procompose p q -/-> r) -> p -/-> Ran q r+curryRan f p = Ran $ \q -> f (Procompose p q)+{-# INLINE curryRan #-}++uncurryRan :: (p -/-> Ran q r) -> Procompose p q -/-> r+uncurryRan f (Procompose p q) = runRan (f p) q+{-# INLINE uncurryRan #-}
src/Data/Profunctor/Rep.hs view
@@ -115,7 +115,7 @@ -- -- This can be used with the combinators from the @lens@ package. ----- @'tabulated' :: 'Corep' f p => 'Iso'' (f d -> c) (p d c)@+-- @'cotabulated' :: 'Corep' f p => 'Iso'' (f d -> c) (p d c)@ cotabulated :: (Corepresentable p, Corepresentable q) => Iso (Corep p d -> c) (Corep q d' -> c') (p d c) (q d' c') cotabulated = dimap cotabulate (fmap corep) {-# INLINE cotabulated #-}
− src/Data/Profunctor/Rift.hs
@@ -1,65 +0,0 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE Rank2Types #-}-{-# LANGUAGE TypeFamilies #-}-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702-{-# LANGUAGE Trustworthy #-}-#endif--------------------------------------------------------------------------------- |--- Copyright   :  (C) 2013 Edward Kmett and Dan Doel--- License     :  BSD-style (see the file LICENSE)------ Maintainer  :  Edward Kmett <ekmett@gmail.com>--- Stability   :  provisional--- Portability :  Rank2Types, TFs---------------------------------------------------------------------------------module Data.Profunctor.Rift-  ( Rift(..)-  , decomposeRift-  , precomposeRift-  ) where--import Control.Category-import Data.Profunctor.Unsafe-import Data.Profunctor.Composition-import Prelude hiding (id,(.))---- | 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 x a -> q x b }----  Ran f g a = forall b. (a -> f b) -> g b--instance (Profunctor p, Profunctor q) => Profunctor (Rift p q) where-  dimap ca bd f = Rift (rmap bd . runRift f . rmap ca)-  {-# INLINE dimap #-}-  lmap ca f = Rift (runRift f . rmap ca)-  {-# INLINE lmap #-}-  rmap bd f = Rift (rmap bd . runRift f)-  {-# INLINE rmap #-}-  bd #. f = Rift (\p -> bd #. runRift f p)-  {-# INLINE ( #. ) #-}-  f .# ca = Rift (\p -> runRift f (ca #. p))-  {-# INLINE (.#) #-}--instance Profunctor q => Functor (Rift p q a) where-  fmap bd f = Rift (rmap bd . runRift f)-  {-# INLINE fmap #-}---- | @'Rift' p p@ forms a 'Monad' in the 'Profunctor' 2-category, which is isomorphic to a Haskell 'Category' instance.-instance p ~ q => Category (Rift p q) where-  id = Rift id-  {-# INLINE id #-}-  Rift f . Rift g = Rift (f . g)-  {-# INLINE (.) #-}---- | The 2-morphism that defines a right Kan lift.------ Note: When @q@ is left adjoint to @'Rift' q (->)@ then 'decomposeRift' is the 'counit' of the adjunction.-decomposeRift :: Procompose q (Rift q p) a b -> p a b-decomposeRift (Procompose q (Rift qp)) = qp q-{-# INLINE decomposeRift #-}--precomposeRift :: Profunctor q => Procompose (Rift p (->)) q a b -> Rift p q a b-precomposeRift (Procompose pf p) = Rift (\pxa -> runRift pf pxa `lmap` p)-{-# INLINE precomposeRift #-}
+ src/Data/Profunctor/Tambara.hs view
@@ -0,0 +1,229 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE MultiParamTypeClasses #-}+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702+{-# 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 ProfunctorComonad Tambara where+  proextract (Tambara p) = dimap (\a -> (a,())) fst p+  produplicate (Tambara p) = Tambara (Tambara $ dimap hither yon p) where+    hither ~(~(x,y),z) = (x,(y,z))+    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 (Left y, s) = Left (y, s)+    hither (Right z, s) = Right (z, s)+    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 ~(~(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 (Left y, s) = Left (y, s)+    hither (Right z, s) = Right (z, s)+    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 ~(~(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+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 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 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+newtype Cotambara p a b = Cotambara { runCotambara :: forall c. p (Either a c) (Either b c) }++instance ProfunctorComonad Cotambara where+  proextract (Cotambara p)   = dimap Left (\(Left a) -> a) p+  produplicate (Cotambara p) = Cotambara (Cotambara $ dimap hither yon p) where+    hither (Left (Left x))   = Left x+    hither (Left (Right y))  = Right (Left y)+    hither (Right z)         = Right (Right z)+    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 Copastro -| Cotambara where+  counit (Copastro f (Cotambara g) h) = dimap h f g+  unit p = Cotambara $ Copastro id p id++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