{-# LANGUAGE TemplateHaskell #-}
module Data.Profunctor.Product (module Data.Profunctor.Product.Class,
module Data.Profunctor.Product.Newtype,
module Data.Profunctor.Product) where
import Prelude hiding (id)
import Data.Profunctor (Profunctor, dimap, lmap, WrappedArrow, Star(..), Costar)
import qualified Data.Profunctor as Profunctor
import Data.Profunctor.Composition (Procompose(..))
import Data.Functor.Contravariant (Contravariant, contramap)
import Data.Functor.Contravariant.Divisible (Divisible(..), Decidable, chosen)
import Control.Category (id)
import Control.Arrow (Arrow, (***), (<<<), arr, (&&&), ArrowChoice, (+++))
import Control.Applicative (Applicative, liftA2, pure, (<*>), Alternative, (<|>), (<$>))
import Data.Monoid (Monoid, mempty, (<>))
import Data.Tagged
import Data.Bifunctor.Biff
import Data.Bifunctor.Clown
import Data.Bifunctor.Joker
import Data.Bifunctor.Product
import Data.Bifunctor.Tannen
import Data.Profunctor.Product.Newtype
import Data.Profunctor.Product.Class
import Data.Profunctor.Product.Flatten
import Data.Profunctor.Product.Tuples
import Data.Profunctor.Product.Tuples.TH (pTns, maxTupleSize, pNs)
(***$) :: ProductProfunctor p => (b -> c) -> p a b -> p a c
***$ :: (b -> c) -> p a b -> p a c
(***$) = (b -> c) -> p a b -> p a c
forall (p :: * -> * -> *) b c a.
Profunctor p =>
(b -> c) -> p a b -> p a c
Profunctor.rmap
instance ProductProfunctor (->) where
purePP :: b -> a -> b
purePP = b -> a -> b
forall (f :: * -> *) a. Applicative f => a -> f a
pure
**** :: (a -> b -> c) -> (a -> b) -> a -> c
(****) = (a -> b -> c) -> (a -> b) -> a -> c
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
(<*>)
instance Arrow arr => ProductProfunctor (WrappedArrow arr) where
empty :: WrappedArrow arr () ()
empty = WrappedArrow arr () ()
forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id
***! :: WrappedArrow arr a b
-> WrappedArrow arr a' b' -> WrappedArrow arr (a, a') (b, b')
(***!) = WrappedArrow arr a b
-> WrappedArrow arr a' b' -> WrappedArrow arr (a, a') (b, b')
forall (a :: * -> * -> *) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
(***)
instance ProductProfunctor Tagged where
purePP :: b -> Tagged a b
purePP = b -> Tagged a b
forall (f :: * -> *) a. Applicative f => a -> f a
pure
**** :: Tagged a (b -> c) -> Tagged a b -> Tagged a c
(****) = Tagged a (b -> c) -> Tagged a b -> Tagged a c
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
(<*>)
instance Applicative f => ProductProfunctor (Star f) where
purePP :: b -> Star f a b
purePP = b -> Star f a b
forall (f :: * -> *) a. Applicative f => a -> f a
pure
**** :: Star f a (b -> c) -> Star f a b -> Star f a c
(****) = Star f a (b -> c) -> Star f a b -> Star f a c
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
(<*>)
instance Functor f => ProductProfunctor (Costar f) where
purePP :: b -> Costar f a b
purePP = b -> Costar f a b
forall (f :: * -> *) a. Applicative f => a -> f a
pure
**** :: Costar f a (b -> c) -> Costar f a b -> Costar f a c
(****) = Costar f a (b -> c) -> Costar f a b -> Costar f a c
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
(<*>)
instance (ProductProfunctor p, ProductProfunctor q) => ProductProfunctor (Procompose p q) where
purePP :: b -> Procompose p q a b
purePP b
a = p () b -> q a () -> Procompose p q a b
forall k k1 k2 (p :: k -> k1 -> *) (x :: k) (c :: k1)
(q :: k2 -> k -> *) (d :: k2).
p x c -> q d x -> Procompose p q d c
Procompose (b -> p () b
forall (p :: * -> * -> *) b a. ProductProfunctor p => b -> p a b
purePP b
a) (() -> q a ()
forall (p :: * -> * -> *) b a. ProductProfunctor p => b -> p a b
purePP ())
Procompose p x (b -> c)
pf q a x
qf **** :: Procompose p q a (b -> c)
-> Procompose p q a b -> Procompose p q a c
**** Procompose p x b
pa q a x
qa =
p (x, x) c -> q a (x, x) -> Procompose p q a c
forall k k1 k2 (p :: k -> k1 -> *) (x :: k) (c :: k1)
(q :: k2 -> k -> *) (d :: k2).
p x c -> q d x -> Procompose p q d c
Procompose (((x, x) -> x) -> p x (b -> c) -> p (x, x) (b -> c)
forall (p :: * -> * -> *) a b c.
Profunctor p =>
(a -> b) -> p b c -> p a c
lmap (x, x) -> x
forall a b. (a, b) -> a
fst p x (b -> c)
pf p (x, x) (b -> c) -> p (x, x) b -> p (x, x) c
forall (p :: * -> * -> *) a b c.
ProductProfunctor p =>
p a (b -> c) -> p a b -> p a c
**** ((x, x) -> x) -> p x b -> p (x, x) b
forall (p :: * -> * -> *) a b c.
Profunctor p =>
(a -> b) -> p b c -> p a c
lmap (x, x) -> x
forall a b. (a, b) -> b
snd p x b
pa) ((,) (x -> x -> (x, x)) -> q a x -> q a (x -> (x, x))
forall (p :: * -> * -> *) b c a.
ProductProfunctor p =>
(b -> c) -> p a b -> p a c
***$ q a x
qf q a (x -> (x, x)) -> q a x -> q a (x, x)
forall (p :: * -> * -> *) a b c.
ProductProfunctor p =>
p a (b -> c) -> p a b -> p a c
**** q a x
qa)
instance (Functor f, Applicative g, ProductProfunctor p) => ProductProfunctor (Biff p f g) where
purePP :: b -> Biff p f g a b
purePP = p (f a) (g b) -> Biff p f g a b
forall k k1 k2 k3 (p :: k -> k1 -> *) (f :: k2 -> k)
(g :: k3 -> k1) (a :: k2) (b :: k3).
p (f a) (g b) -> Biff p f g a b
Biff (p (f a) (g b) -> Biff p f g a b)
-> (b -> p (f a) (g b)) -> b -> Biff p f g a b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. g b -> p (f a) (g b)
forall (p :: * -> * -> *) b a. ProductProfunctor p => b -> p a b
purePP (g b -> p (f a) (g b)) -> (b -> g b) -> b -> p (f a) (g b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> g b
forall (f :: * -> *) a. Applicative f => a -> f a
pure
Biff p (f a) (g (b -> c))
abc **** :: Biff p f g a (b -> c) -> Biff p f g a b -> Biff p f g a c
**** Biff p (f a) (g b)
ab = p (f a) (g c) -> Biff p f g a c
forall k k1 k2 k3 (p :: k -> k1 -> *) (f :: k2 -> k)
(g :: k3 -> k1) (a :: k2) (b :: k3).
p (f a) (g b) -> Biff p f g a b
Biff (p (f a) (g c) -> Biff p f g a c)
-> p (f a) (g c) -> Biff p f g a c
forall a b. (a -> b) -> a -> b
$ g (b -> c) -> g b -> g c
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
(<*>) (g (b -> c) -> g b -> g c)
-> p (f a) (g (b -> c)) -> p (f a) (g b -> g c)
forall (p :: * -> * -> *) b c a.
ProductProfunctor p =>
(b -> c) -> p a b -> p a c
***$ p (f a) (g (b -> c))
abc p (f a) (g b -> g c) -> p (f a) (g b) -> p (f a) (g c)
forall (p :: * -> * -> *) a b c.
ProductProfunctor p =>
p a (b -> c) -> p a b -> p a c
**** p (f a) (g b)
ab
instance Applicative f => ProductProfunctor (Joker f) where
purePP :: b -> Joker f a b
purePP = f b -> Joker f a b
forall k k1 (g :: k -> *) (a :: k1) (b :: k). g b -> Joker g a b
Joker (f b -> Joker f a b) -> (b -> f b) -> b -> Joker f a b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> f b
forall (f :: * -> *) a. Applicative f => a -> f a
pure
Joker f (b -> c)
bc **** :: Joker f a (b -> c) -> Joker f a b -> Joker f a c
**** Joker f b
b = f c -> Joker f a c
forall k k1 (g :: k -> *) (a :: k1) (b :: k). g b -> Joker g a b
Joker (f c -> Joker f a c) -> f c -> Joker f a c
forall a b. (a -> b) -> a -> b
$ f (b -> c)
bc f (b -> c) -> f b -> f c
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> f b
b
instance Divisible f => ProductProfunctor (Clown f) where
purePP :: b -> Clown f a b
purePP b
_ = f a -> Clown f a b
forall k k1 (f :: k -> *) (a :: k) (b :: k1). f a -> Clown f a b
Clown f a
forall (f :: * -> *) a. Divisible f => f a
conquer
Clown f a
l **** :: Clown f a (b -> c) -> Clown f a b -> Clown f a c
**** Clown f a
r = f a -> Clown f a c
forall k k1 (f :: k -> *) (a :: k) (b :: k1). f a -> Clown f a b
Clown (f a -> Clown f a c) -> f a -> Clown f a c
forall a b. (a -> b) -> a -> b
$ (a -> (a, a)) -> f a -> f a -> f a
forall (f :: * -> *) a b c.
Divisible f =>
(a -> (b, c)) -> f b -> f c -> f a
divide (\a
a -> (a
a, a
a)) f a
l f a
r
instance (ProductProfunctor p, ProductProfunctor q) => ProductProfunctor (Product p q) where
purePP :: b -> Product p q a b
purePP b
a = p a b -> q a b -> Product p q a b
forall k k1 (f :: k -> k1 -> *) (g :: k -> k1 -> *) (a :: k)
(b :: k1).
f a b -> g a b -> Product f g a b
Pair (b -> p a b
forall (p :: * -> * -> *) b a. ProductProfunctor p => b -> p a b
purePP b
a) (b -> q a b
forall (p :: * -> * -> *) b a. ProductProfunctor p => b -> p a b
purePP b
a)
Pair p a (b -> c)
l1 q a (b -> c)
l2 **** :: Product p q a (b -> c) -> Product p q a b -> Product p q a c
**** Pair p a b
r1 q a b
r2 = p a c -> q a c -> Product p q a c
forall k k1 (f :: k -> k1 -> *) (g :: k -> k1 -> *) (a :: k)
(b :: k1).
f a b -> g a b -> Product f g a b
Pair (p a (b -> c)
l1 p a (b -> c) -> p a b -> p a c
forall (p :: * -> * -> *) a b c.
ProductProfunctor p =>
p a (b -> c) -> p a b -> p a c
**** p a b
r1) (q a (b -> c)
l2 q a (b -> c) -> q a b -> q a c
forall (p :: * -> * -> *) a b c.
ProductProfunctor p =>
p a (b -> c) -> p a b -> p a c
**** q a b
r2)
instance (Applicative f, ProductProfunctor p) => ProductProfunctor (Tannen f p) where
purePP :: b -> Tannen f p a b
purePP = f (p a b) -> Tannen f p a b
forall k k1 k2 (f :: k -> *) (p :: k1 -> k2 -> k) (a :: k1)
(b :: k2).
f (p a b) -> Tannen f p a b
Tannen (f (p a b) -> Tannen f p a b)
-> (b -> f (p a b)) -> b -> Tannen f p a b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. p a b -> f (p a b)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (p a b -> f (p a b)) -> (b -> p a b) -> b -> f (p a b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b -> p a b
forall (p :: * -> * -> *) b a. ProductProfunctor p => b -> p a b
purePP
Tannen f (p a (b -> c))
f **** :: Tannen f p a (b -> c) -> Tannen f p a b -> Tannen f p a c
**** Tannen f (p a b)
a = f (p a c) -> Tannen f p a c
forall k k1 k2 (f :: k -> *) (p :: k1 -> k2 -> k) (a :: k1)
(b :: k2).
f (p a b) -> Tannen f p a b
Tannen (f (p a c) -> Tannen f p a c) -> f (p a c) -> Tannen f p a c
forall a b. (a -> b) -> a -> b
$ (p a (b -> c) -> p a b -> p a c)
-> f (p a (b -> c)) -> f (p a b) -> f (p a c)
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 p a (b -> c) -> p a b -> p a c
forall (p :: * -> * -> *) a b c.
ProductProfunctor p =>
p a (b -> c) -> p a b -> p a c
(****) f (p a (b -> c))
f f (p a b)
a
instance SumProfunctor (->) where
a -> b
f +++! :: (a -> b) -> (a' -> b') -> Either a a' -> Either b b'
+++! a' -> b'
g = (a -> Either b b')
-> (a' -> Either b b') -> Either a a' -> Either b b'
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (b -> Either b b'
forall a b. a -> Either a b
Left (b -> Either b b') -> (a -> b) -> a -> Either b b'
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
f) (b' -> Either b b'
forall a b. b -> Either a b
Right (b' -> Either b b') -> (a' -> b') -> a' -> Either b b'
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a' -> b'
g)
instance ArrowChoice arr => SumProfunctor (WrappedArrow arr) where
+++! :: WrappedArrow arr a b
-> WrappedArrow arr a' b'
-> WrappedArrow arr (Either a a') (Either b b')
(+++!) = WrappedArrow arr a b
-> WrappedArrow arr a' b'
-> WrappedArrow arr (Either a a') (Either b b')
forall (a :: * -> * -> *) b c b' c'.
ArrowChoice a =>
a b c -> a b' c' -> a (Either b b') (Either c c')
(+++)
instance Applicative f => SumProfunctor (Star f) where
Star a -> f b
f +++! :: Star f a b -> Star f a' b' -> Star f (Either a a') (Either b b')
+++! Star a' -> f b'
g = (Either a a' -> f (Either b b'))
-> Star f (Either a a') (Either b b')
forall k (f :: k -> *) d (c :: k). (d -> f c) -> Star f d c
Star ((Either a a' -> f (Either b b'))
-> Star f (Either a a') (Either b b'))
-> (Either a a' -> f (Either b b'))
-> Star f (Either a a') (Either b b')
forall a b. (a -> b) -> a -> b
$ (a -> f (Either b b'))
-> (a' -> f (Either b b')) -> Either a a' -> f (Either b b')
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ((b -> Either b b') -> f b -> f (Either b b')
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap b -> Either b b'
forall a b. a -> Either a b
Left (f b -> f (Either b b')) -> (a -> f b) -> a -> f (Either b b')
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> f b
f) ((b' -> Either b b') -> f b' -> f (Either b b')
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap b' -> Either b b'
forall a b. b -> Either a b
Right (f b' -> f (Either b b')) -> (a' -> f b') -> a' -> f (Either b b')
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a' -> f b'
g)
instance (SumProfunctor p, SumProfunctor q) => SumProfunctor (Procompose p q) where
Procompose p x b
pa q a x
qa +++! :: Procompose p q a b
-> Procompose p q a' b'
-> Procompose p q (Either a a') (Either b b')
+++! Procompose p x b'
pb q a' x
qb = p (Either x x) (Either b b')
-> q (Either a a') (Either x x)
-> Procompose p q (Either a a') (Either b b')
forall k k1 k2 (p :: k -> k1 -> *) (x :: k) (c :: k1)
(q :: k2 -> k -> *) (d :: k2).
p x c -> q d x -> Procompose p q d c
Procompose (p x b
pa p x b -> p x b' -> p (Either x x) (Either b b')
forall (p :: * -> * -> *) a b a' b'.
SumProfunctor p =>
p a b -> p a' b' -> p (Either a a') (Either b b')
+++! p x b'
pb) (q a x
qa q a x -> q a' x -> q (Either a a') (Either x x)
forall (p :: * -> * -> *) a b a' b'.
SumProfunctor p =>
p a b -> p a' b' -> p (Either a a') (Either b b')
+++! q a' x
qb)
instance Alternative f => SumProfunctor (Joker f) where
Joker f b
f +++! :: Joker f a b -> Joker f a' b' -> Joker f (Either a a') (Either b b')
+++! Joker f b'
g = f (Either b b') -> Joker f (Either a a') (Either b b')
forall k k1 (g :: k -> *) (a :: k1) (b :: k). g b -> Joker g a b
Joker (f (Either b b') -> Joker f (Either a a') (Either b b'))
-> f (Either b b') -> Joker f (Either a a') (Either b b')
forall a b. (a -> b) -> a -> b
$ b -> Either b b'
forall a b. a -> Either a b
Left (b -> Either b b') -> f b -> f (Either b b')
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f b
f f (Either b b') -> f (Either b b') -> f (Either b b')
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> b' -> Either b b'
forall a b. b -> Either a b
Right (b' -> Either b b') -> f b' -> f (Either b b')
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> f b'
g
instance Decidable f => SumProfunctor (Clown f) where
Clown f a
f +++! :: Clown f a b -> Clown f a' b' -> Clown f (Either a a') (Either b b')
+++! Clown f a'
g = f (Either a a') -> Clown f (Either a a') (Either b b')
forall k k1 (f :: k -> *) (a :: k) (b :: k1). f a -> Clown f a b
Clown (f (Either a a') -> Clown f (Either a a') (Either b b'))
-> f (Either a a') -> Clown f (Either a a') (Either b b')
forall a b. (a -> b) -> a -> b
$ f a -> f a' -> f (Either a a')
forall (f :: * -> *) b c.
Decidable f =>
f b -> f c -> f (Either b c)
chosen f a
f f a'
g
instance (SumProfunctor p, SumProfunctor q) => SumProfunctor (Product p q) where
Pair p a b
l1 q a b
l2 +++! :: Product p q a b
-> Product p q a' b' -> Product p q (Either a a') (Either b b')
+++! Pair p a' b'
r1 q a' b'
r2 = p (Either a a') (Either b b')
-> q (Either a a') (Either b b')
-> Product p q (Either a a') (Either b b')
forall k k1 (f :: k -> k1 -> *) (g :: k -> k1 -> *) (a :: k)
(b :: k1).
f a b -> g a b -> Product f g a b
Pair (p a b
l1 p a b -> p a' b' -> p (Either a a') (Either b b')
forall (p :: * -> * -> *) a b a' b'.
SumProfunctor p =>
p a b -> p a' b' -> p (Either a a') (Either b b')
+++! p a' b'
r1) (q a b
l2 q a b -> q a' b' -> q (Either a a') (Either b b')
forall (p :: * -> * -> *) a b a' b'.
SumProfunctor p =>
p a b -> p a' b' -> p (Either a a') (Either b b')
+++! q a' b'
r2)
instance (Applicative f, SumProfunctor p) => SumProfunctor (Tannen f p) where
Tannen f (p a b)
l +++! :: Tannen f p a b
-> Tannen f p a' b' -> Tannen f p (Either a a') (Either b b')
+++! Tannen f (p a' b')
r = f (p (Either a a') (Either b b'))
-> Tannen f p (Either a a') (Either b b')
forall k k1 k2 (f :: k -> *) (p :: k1 -> k2 -> k) (a :: k1)
(b :: k2).
f (p a b) -> Tannen f p a b
Tannen (f (p (Either a a') (Either b b'))
-> Tannen f p (Either a a') (Either b b'))
-> f (p (Either a a') (Either b b'))
-> Tannen f p (Either a a') (Either b b')
forall a b. (a -> b) -> a -> b
$ (p a b -> p a' b' -> p (Either a a') (Either b b'))
-> f (p a b) -> f (p a' b') -> f (p (Either a a') (Either b b'))
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 p a b -> p a' b' -> p (Either a a') (Either b b')
forall (p :: * -> * -> *) a b a' b'.
SumProfunctor p =>
p a b -> p a' b' -> p (Either a a') (Either b b')
(+++!) f (p a b)
l f (p a' b')
r
list :: (ProductProfunctor p, SumProfunctor p) => p a b -> p [a] [b]
list :: p a b -> p [a] [b]
list p a b
p = ([a] -> Either () (a, [a]))
-> (Either () (b, [b]) -> [b])
-> p (Either () (a, [a])) (Either () (b, [b]))
-> p [a] [b]
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
Profunctor.dimap [a] -> Either () (a, [a])
forall a. [a] -> Either () (a, [a])
fromList Either () (b, [b]) -> [b]
forall a. Either () (a, [a]) -> [a]
toList (p () ()
forall (p :: * -> * -> *). ProductProfunctor p => p () ()
empty p () ()
-> p (a, [a]) (b, [b])
-> p (Either () (a, [a])) (Either () (b, [b]))
forall (p :: * -> * -> *) a b a' b'.
SumProfunctor p =>
p a b -> p a' b' -> p (Either a a') (Either b b')
+++! (p a b
p p a b -> p [a] [b] -> p (a, [a]) (b, [b])
forall (p :: * -> * -> *) a b a' b'.
ProductProfunctor p =>
p a b -> p a' b' -> p (a, a') (b, b')
***! p a b -> p [a] [b]
forall (p :: * -> * -> *) a b.
(ProductProfunctor p, SumProfunctor p) =>
p a b -> p [a] [b]
list p a b
p))
where toList :: Either () (a, [a]) -> [a]
toList :: Either () (a, [a]) -> [a]
toList = (() -> [a]) -> ((a, [a]) -> [a]) -> Either () (a, [a]) -> [a]
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ([a] -> () -> [a]
forall b a. b -> a -> b
const []) ((a -> [a] -> [a]) -> (a, [a]) -> [a]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (:))
fromList :: [a] -> Either () (a, [a])
fromList :: [a] -> Either () (a, [a])
fromList [] = () -> Either () (a, [a])
forall a b. a -> Either a b
Left ()
fromList (a
a:[a]
as) = (a, [a]) -> Either () (a, [a])
forall a b. b -> Either a b
Right (a
a, [a]
as)