module Data.Bifunctor.Monoidal where

import Prelude hiding ((.), id)
import Control.Applicative
import Control.Category
import Control.Category.Tensor
import Data.Biapplicative
import Data.Bifunctor.Clown
import Data.Bifunctor.Joker
import Data.Profunctor
import Data.Semigroupoid
import Data.These
import Data.Void

class (Associative t1 cat, Associative t2 cat, Associative to cat) => Semigroupal cat t1 t2 to f where
  combine :: cat (to (f x y) (f x' y')) (f (t1 x x') (t2 y y'))

instance Profunctor p => Semigroupal (->) (,) Either Either p where
  combine :: Either (p x y) (p x' y') -> p (x, x') (Either y y')
  combine :: Either (p x y) (p x' y') -> p (x, x') (Either y y')
combine = (p x y -> p (x, x') (Either y y'))
-> (p x' y' -> p (x, x') (Either y y'))
-> Either (p x y) (p x' y')
-> p (x, x') (Either y y')
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (((x, x') -> x)
-> (y -> Either y y') -> p x y -> p (x, x') (Either y y')
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap (x, x') -> x
forall a b. (a, b) -> a
fst y -> Either y y'
forall a b. a -> Either a b
Left) (((x, x') -> x')
-> (y' -> Either y y') -> p x' y' -> p (x, x') (Either y y')
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b) -> (c -> d) -> p b c -> p a d
dimap (x, x') -> x'
forall a b. (a, b) -> b
snd y' -> Either y y'
forall a b. b -> Either a b
Right)

instance Semigroupal (->) (,) (,) (,) (,) where
  combine :: ((x, y), (x', y')) -> ((x, x'), (y, y'))
  combine :: ((x, y), (x', y')) -> ((x, x'), (y, y'))
combine ((x
x, y
y), (x'
x', y'
y')) = ((x
x, x'
x'), (y
y, y'
y'))
  -- NOTE: This version could be used for a more general abstraction
  -- of products in a category:
  -- combine =
  --   let fwd' = fwd assoc
  --       bwd' = bwd assoc
  --   in second swap . swap . fwd' . swap . first (bwd' . first swap) . fwd'

instance Semigroupal (->) Either Either Either (,) where
  combine :: Either (x, y) (x', y') -> (Either x x', Either y y')
  combine :: Either (x, y) (x', y') -> (Either x x', Either y y')
combine = ((x, y) -> (Either x x', Either y y'))
-> ((x', y') -> (Either x x', Either y y'))
-> Either (x, y) (x', y')
-> (Either x x', Either y y')
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ((x -> Either x x')
-> (y -> Either y y') -> (x, y) -> (Either x x', Either y y')
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap x -> Either x x'
forall a b. a -> Either a b
Left y -> Either y y'
forall a b. a -> Either a b
Left) ((x' -> Either x x')
-> (y' -> Either y y') -> (x', y') -> (Either x x', Either y y')
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap x' -> Either x x'
forall a b. b -> Either a b
Right y' -> Either y y'
forall a b. b -> Either a b
Right)

instance Semigroupal (->) Either Either Either Either where
  combine :: Either (Either x y) (Either x' y') -> Either (Either x x') (Either y y')
  combine :: Either (Either x y) (Either x' y')
-> Either (Either x x') (Either y y')
combine = (Either x y -> Either (Either x x') (Either y y'))
-> (Either x' y' -> Either (Either x x') (Either y y'))
-> Either (Either x y) (Either x' y')
-> Either (Either x x') (Either y y')
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ((x -> Either x x')
-> (y -> Either y y')
-> Either x y
-> Either (Either x x') (Either y y')
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap x -> Either x x'
forall a b. a -> Either a b
Left y -> Either y y'
forall a b. a -> Either a b
Left) ((x' -> Either x x')
-> (y' -> Either y y')
-> Either x' y'
-> Either (Either x x') (Either y y')
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap x' -> Either x x'
forall a b. b -> Either a b
Right y' -> Either y y'
forall a b. b -> Either a b
Right)

instance Semigroupal (->) Either (,) (,) Either where
  combine :: (Either x y, Either x' y') -> Either (Either x x') (y, y')
  combine :: (Either x y, Either x' y') -> Either (Either x x') (y, y')
combine = \case
    (Left x
x, Left x'
_) -> Either x x' -> Either (Either x x') (y, y')
forall a b. a -> Either a b
Left (Either x x' -> Either (Either x x') (y, y'))
-> Either x x' -> Either (Either x x') (y, y')
forall a b. (a -> b) -> a -> b
$ x -> Either x x'
forall a b. a -> Either a b
Left x
x
    (Left x
x, Right y'
_) -> Either x x' -> Either (Either x x') (y, y')
forall a b. a -> Either a b
Left (Either x x' -> Either (Either x x') (y, y'))
-> Either x x' -> Either (Either x x') (y, y')
forall a b. (a -> b) -> a -> b
$ x -> Either x x'
forall a b. a -> Either a b
Left x
x
    (Right y
_, Left x'
x') -> Either x x' -> Either (Either x x') (y, y')
forall a b. a -> Either a b
Left (Either x x' -> Either (Either x x') (y, y'))
-> Either x x' -> Either (Either x x') (y, y')
forall a b. (a -> b) -> a -> b
$ x' -> Either x x'
forall a b. b -> Either a b
Right x'
x'
    (Right y
y, Right y'
y') -> (y, y') -> Either (Either x x') (y, y')
forall a b. b -> Either a b
Right (y
y, y'
y')

instance Semigroupal (->) These (,) (,) Either where
  combine :: (Either x y, Either x' y') -> Either (These x x') (y, y')
  combine :: (Either x y, Either x' y') -> Either (These x x') (y, y')
combine = \case
    (Left x
x, Left x'
x') -> These x x' -> Either (These x x') (y, y')
forall a b. a -> Either a b
Left (These x x' -> Either (These x x') (y, y'))
-> These x x' -> Either (These x x') (y, y')
forall a b. (a -> b) -> a -> b
$ x -> x' -> These x x'
forall a b. a -> b -> These a b
These x
x x'
x'
    (Left x
x, Right y'
_) -> These x x' -> Either (These x x') (y, y')
forall a b. a -> Either a b
Left (These x x' -> Either (These x x') (y, y'))
-> These x x' -> Either (These x x') (y, y')
forall a b. (a -> b) -> a -> b
$ x -> These x x'
forall a b. a -> These a b
This x
x
    (Right y
_, Left x'
x') -> These x x' -> Either (These x x') (y, y')
forall a b. a -> Either a b
Left (These x x' -> Either (These x x') (y, y'))
-> These x x' -> Either (These x x') (y, y')
forall a b. (a -> b) -> a -> b
$ x' -> These x x'
forall a b. b -> These a b
That x'
x'
    (Right y
y, Right y'
y') -> (y, y') -> Either (These x x') (y, y')
forall a b. b -> Either a b
Right (y
y, y'
y')

instance Semigroupal (->) (,) (,) (,) (->) where
  combine :: (x -> y, x' -> y') -> (x, x') -> (y, y')
  combine :: (x -> y, x' -> y') -> (x, x') -> (y, y')
combine (x -> y, x' -> y')
fs = ((x -> y) -> (x' -> y') -> (x, x') -> (y, y'))
-> (x -> y, x' -> y') -> (x, x') -> (y, y')
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (x -> y) -> (x' -> y') -> (x, x') -> (y, y')
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (x -> y, x' -> y')
fs

instance Semigroupal (->) Either Either (,) (->) where
  combine :: (x -> y, x' -> y') -> Either x x' -> Either y y'
  combine :: (x -> y, x' -> y') -> Either x x' -> Either y y'
combine (x -> y, x' -> y')
fs = (x -> Either y y')
-> (x' -> Either y y') -> Either x x' -> Either y y'
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (y -> Either y y'
forall a b. a -> Either a b
Left (y -> Either y y') -> (x -> y) -> x -> Either y y'
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (x -> y, x' -> y') -> x -> y
forall a b. (a, b) -> a
fst (x -> y, x' -> y')
fs) (y' -> Either y y'
forall a b. b -> Either a b
Right (y' -> Either y y') -> (x' -> y') -> x' -> Either y y'
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (x -> y, x' -> y') -> x' -> y'
forall a b. (a, b) -> b
snd (x -> y, x' -> y')
fs)

instance Applicative f => Semigroupal (->) (,) (,) (,) (Joker f) where
  combine :: (Joker f x y, Joker f x' y') -> Joker f (x, x') (y, y')
  combine :: (Joker f x y, Joker f x' y') -> Joker f (x, x') (y, y')
combine = (Joker f x y -> Joker f x' y' -> Joker f (x, x') (y, y'))
-> (Joker f x y, Joker f x' y') -> Joker f (x, x') (y, y')
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((Joker f x y -> Joker f x' y' -> Joker f (x, x') (y, y'))
 -> (Joker f x y, Joker f x' y') -> Joker f (x, x') (y, y'))
-> (Joker f x y -> Joker f x' y' -> Joker f (x, x') (y, y'))
-> (Joker f x y, Joker f x' y')
-> Joker f (x, x') (y, y')
forall a b. (a -> b) -> a -> b
$ (x -> x' -> (x, x'))
-> (y -> y' -> (y, y'))
-> Joker f x y
-> Joker f x' y'
-> Joker f (x, x') (y, y')
forall (p :: * -> * -> *) a b c d e f.
Biapplicative p =>
(a -> b -> c) -> (d -> e -> f) -> p a d -> p b e -> p c f
biliftA2 (,) (,)

instance Alternative f => Semigroupal (->) Either Either (,) (Joker f) where
  combine :: (Joker f x y, Joker f x' y') -> Joker f (Either x x') (Either y y')
  combine :: (Joker f x y, Joker f x' y') -> Joker f (Either x x') (Either y y')
combine  = (Joker f x y
 -> Joker f x' y' -> Joker f (Either x x') (Either y y'))
-> (Joker f x y, Joker f x' y')
-> Joker f (Either x x') (Either y y')
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((Joker f x y
  -> Joker f x' y' -> Joker f (Either x x') (Either y y'))
 -> (Joker f x y, Joker f x' y')
 -> Joker f (Either x x') (Either y y'))
-> (Joker f x y
    -> Joker f x' y' -> Joker f (Either x x') (Either y y'))
-> (Joker f x y, Joker f x' y')
-> Joker f (Either x x') (Either y y')
forall a b. (a -> b) -> a -> b
$ (x -> x' -> Either x x')
-> (y -> y' -> Either y y')
-> Joker f x y
-> Joker f x' y'
-> Joker f (Either x x') (Either y y')
forall (p :: * -> * -> *) a b c d e f.
Biapplicative p =>
(a -> b -> c) -> (d -> e -> f) -> p a d -> p b e -> p c f
biliftA2 (\x
_ x'
x' -> x' -> Either x x'
forall a b. b -> Either a b
Right x'
x') (\y
_ y'
y' -> y' -> Either y y'
forall a b. b -> Either a b
Right y'
y')

instance Functor f => Semigroupal (->) Either Either Either (Joker f) where
  combine :: Either (Joker f x y) (Joker f x' y') -> Joker f (Either x x') (Either y y')
  combine :: Either (Joker f x y) (Joker f x' y')
-> Joker f (Either x x') (Either y y')
combine = (Joker f x y -> Joker f (Either x x') (Either y y'))
-> (Joker f x' y' -> Joker f (Either x x') (Either y y'))
-> Either (Joker f x y) (Joker f x' y')
-> Joker f (Either x x') (Either y y')
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (f (Either y y') -> Joker f (Either x x') (Either y y')
forall k k1 (g :: k -> *) (a :: k1) (b :: k). g b -> Joker g a b
Joker (f (Either y y') -> Joker f (Either x x') (Either y y'))
-> (Joker f x y -> f (Either y y'))
-> Joker f x y
-> Joker f (Either x x') (Either y y')
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (y -> Either y y') -> f y -> f (Either y y')
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap y -> Either y y'
forall a b. a -> Either a b
Left (f y -> f (Either y y'))
-> (Joker f x y -> f y) -> Joker f x y -> f (Either y y')
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Joker f x y -> f y
forall k1 (g :: k1 -> *) k2 (a :: k2) (b :: k1). Joker g a b -> g b
runJoker ) (f (Either y y') -> Joker f (Either x x') (Either y y')
forall k k1 (g :: k -> *) (a :: k1) (b :: k). g b -> Joker g a b
Joker (f (Either y y') -> Joker f (Either x x') (Either y y'))
-> (Joker f x' y' -> f (Either y y'))
-> Joker f x' y'
-> Joker f (Either x x') (Either y y')
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (y' -> Either y y') -> f y' -> f (Either y y')
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap y' -> Either y y'
forall a b. b -> Either a b
Right (f y' -> f (Either y y'))
-> (Joker f x' y' -> f y') -> Joker f x' y' -> f (Either y y')
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Joker f x' y' -> f y'
forall k1 (g :: k1 -> *) k2 (a :: k2) (b :: k1). Joker g a b -> g b
runJoker)

instance Applicative f => Semigroupal (->) (,) (,) (,) (Clown f) where
  combine :: (Clown f x y, Clown f x' y') -> Clown f (x, x') (y, y')
  combine :: (Clown f x y, Clown f x' y') -> Clown f (x, x') (y, y')
combine = (Clown f x y -> Clown f x' y' -> Clown f (x, x') (y, y'))
-> (Clown f x y, Clown f x' y') -> Clown f (x, x') (y, y')
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((Clown f x y -> Clown f x' y' -> Clown f (x, x') (y, y'))
 -> (Clown f x y, Clown f x' y') -> Clown f (x, x') (y, y'))
-> (Clown f x y -> Clown f x' y' -> Clown f (x, x') (y, y'))
-> (Clown f x y, Clown f x' y')
-> Clown f (x, x') (y, y')
forall a b. (a -> b) -> a -> b
$ (x -> x' -> (x, x'))
-> (y -> y' -> (y, y'))
-> Clown f x y
-> Clown f x' y'
-> Clown f (x, x') (y, y')
forall (p :: * -> * -> *) a b c d e f.
Biapplicative p =>
(a -> b -> c) -> (d -> e -> f) -> p a d -> p b e -> p c f
biliftA2 (,) (,)

instance Alternative f => Semigroupal (->) Either Either (,) (Clown f) where
  combine :: (Clown f x y, Clown f x' y') -> Clown f (Either x x') (Either y y')
  combine :: (Clown f x y, Clown f x' y') -> Clown f (Either x x') (Either y y')
combine = (Clown f x y
 -> Clown f x' y' -> Clown f (Either x x') (Either y y'))
-> (Clown f x y, Clown f x' y')
-> Clown f (Either x x') (Either y y')
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((Clown f x y
  -> Clown f x' y' -> Clown f (Either x x') (Either y y'))
 -> (Clown f x y, Clown f x' y')
 -> Clown f (Either x x') (Either y y'))
-> (Clown f x y
    -> Clown f x' y' -> Clown f (Either x x') (Either y y'))
-> (Clown f x y, Clown f x' y')
-> Clown f (Either x x') (Either y y')
forall a b. (a -> b) -> a -> b
$ (x -> x' -> Either x x')
-> (y -> y' -> Either y y')
-> Clown f x y
-> Clown f x' y'
-> Clown f (Either x x') (Either y y')
forall (p :: * -> * -> *) a b c d e f.
Biapplicative p =>
(a -> b -> c) -> (d -> e -> f) -> p a d -> p b e -> p c f
biliftA2 (\x
_ x'
x' -> x' -> Either x x'
forall a b. b -> Either a b
Right x'
x') (\y
_ y'
y' -> y' -> Either y y'
forall a b. b -> Either a b
Right y'
y')

instance Applicative f => Semigroupal (->) (,) (,) (,) (Star f) where
  combine :: (Star f x y, Star f x' y') -> Star f (x, x') (y, y')
  combine :: (Star f x y, Star f x' y') -> Star f (x, x') (y, y')
combine (Star x -> f y
fxy, Star x' -> f y'
fxy') = ((x, x') -> f (y, y')) -> Star f (x, x') (y, y')
forall k (f :: k -> *) d (c :: k). (d -> f c) -> Star f d c
Star (((x, x') -> f (y, y')) -> Star f (x, x') (y, y'))
-> ((x, x') -> f (y, y')) -> Star f (x, x') (y, y')
forall a b. (a -> b) -> a -> b
$ \(x
x, x'
x') -> (y -> y' -> (y, y')) -> f y -> f y' -> f (y, y')
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (,) (x -> f y
fxy x
x) (x' -> f y'
fxy' x'
x')

instance Functor f => Semigroupal (->) Either Either (,) (Star f) where
  combine :: (Star f x y, Star f x' y') -> Star f (Either x x') (Either y y')
  combine :: (Star f x y, Star f x' y') -> Star f (Either x x') (Either y y')
combine (Star x -> f y
fxy, Star x' -> f y'
fxy') = (Either x x' -> f (Either y y'))
-> Star f (Either x x') (Either y y')
forall k (f :: k -> *) d (c :: k). (d -> f c) -> Star f d c
Star ((Either x x' -> f (Either y y'))
 -> Star f (Either x x') (Either y y'))
-> (Either x x' -> f (Either y y'))
-> Star f (Either x x') (Either y y')
forall a b. (a -> b) -> a -> b
$ (x -> f (Either y y'))
-> (x' -> f (Either y y')) -> Either x x' -> f (Either y y')
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ((y -> Either y y') -> f y -> f (Either y y')
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap y -> Either y y'
forall a b. a -> Either a b
Left (f y -> f (Either y y')) -> (x -> f y) -> x -> f (Either y y')
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. x -> f y
fxy) ((y' -> Either y y') -> f y' -> f (Either y y')
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap y' -> Either y y'
forall a b. b -> Either a b
Right (f y' -> f (Either y y')) -> (x' -> f y') -> x' -> f (Either y y')
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. x' -> f y'
fxy')

instance Alternative f => Semigroupal (->) Either Either Either (Star f) where
  combine :: Either (Star f x y) (Star f x' y') -> Star f (Either x x') (Either y y')
  combine :: Either (Star f x y) (Star f x' y')
-> Star f (Either x x') (Either y y')
combine = \case
    Left (Star x -> f y
fxy) -> (Either x x' -> f (Either y y'))
-> Star f (Either x x') (Either y y')
forall k (f :: k -> *) d (c :: k). (d -> f c) -> Star f d c
Star ((Either x x' -> f (Either y y'))
 -> Star f (Either x x') (Either y y'))
-> (Either x x' -> f (Either y y'))
-> Star f (Either x x') (Either y y')
forall a b. (a -> b) -> a -> b
$ (x -> f (Either y y'))
-> (x' -> f (Either y y')) -> Either x x' -> f (Either y y')
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ((y -> Either y y') -> f y -> f (Either y y')
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap y -> Either y y'
forall a b. a -> Either a b
Left (f y -> f (Either y y')) -> (x -> f y) -> x -> f (Either y y')
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. x -> f y
fxy) (f (Either y y') -> x' -> f (Either y y')
forall a b. a -> b -> a
const f (Either y y')
forall (f :: * -> *) a. Alternative f => f a
empty)
    Right (Star x' -> f y'
fxy') -> (Either x x' -> f (Either y y'))
-> Star f (Either x x') (Either y y')
forall k (f :: k -> *) d (c :: k). (d -> f c) -> Star f d c
Star ((Either x x' -> f (Either y y'))
 -> Star f (Either x x') (Either y y'))
-> (Either x x' -> f (Either y y'))
-> Star f (Either x x') (Either y y')
forall a b. (a -> b) -> a -> b
$ (x -> f (Either y y'))
-> (x' -> f (Either y y')) -> Either x x' -> f (Either y y')
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (f (Either y y') -> x -> f (Either y y')
forall a b. a -> b -> a
const f (Either y y')
forall (f :: * -> *) a. Alternative f => f a
empty) ((y' -> Either y y') -> f y' -> f (Either y y')
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap y' -> Either y y'
forall a b. b -> Either a b
Right (f y' -> f (Either y y')) -> (x' -> f y') -> x' -> f (Either y y')
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. x' -> f y'
fxy')

instance Alternative f => Semigroupal (->) (,) Either (,) (Star f) where
  combine :: (Star f x y, Star f x' y') -> Star f (x, x') (Either y y')
  combine :: (Star f x y, Star f x' y') -> Star f (x, x') (Either y y')
combine (Star x -> f y
f, Star x' -> f y'
g) = ((x, x') -> f (Either y y')) -> Star f (x, x') (Either y y')
forall k (f :: k -> *) d (c :: k). (d -> f c) -> Star f d c
Star (((x, x') -> f (Either y y')) -> Star f (x, x') (Either y y'))
-> ((x, x') -> f (Either y y')) -> Star f (x, x') (Either y y')
forall a b. (a -> b) -> a -> b
$ \(x
x, x'
x') -> (y -> Either y y'
forall a b. a -> Either a b
Left (y -> Either y y') -> f y -> f (Either y y')
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> x -> f y
f x
x) f (Either y y') -> f (Either y y') -> f (Either y y')
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (y' -> Either y y'
forall a b. b -> Either a b
Right (y' -> Either y y') -> f y' -> f (Either y y')
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> x' -> f y'
g x'
x')

instance Alternative f => Semigroupal (->) (,) (,) (,) (Forget (f r)) where
  combine :: (Forget (f r) x y, Forget (f r) x' y') -> Forget (f r) (x, x') (y, y')
  combine :: (Forget (f r) x y, Forget (f r) x' y')
-> Forget (f r) (x, x') (y, y')
combine (Forget x -> f r
f, Forget x' -> f r
g) = ((x, x') -> f r) -> Forget (f r) (x, x') (y, y')
forall k r a (b :: k). (a -> r) -> Forget r a b
Forget (((x, x') -> f r) -> Forget (f r) (x, x') (y, y'))
-> ((x, x') -> f r) -> Forget (f r) (x, x') (y, y')
forall a b. (a -> b) -> a -> b
$ \(x
x, x'
x') -> x -> f r
f x
x f r -> f r -> f r
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> x' -> f r
g x'
x'

instance Semigroupal (->) Either Either (,) (Forget (f r)) where
  combine :: (Forget (f r) x y, Forget (f r) x' y') -> Forget (f r) (Either x x') (Either y y')
  combine :: (Forget (f r) x y, Forget (f r) x' y')
-> Forget (f r) (Either x x') (Either y y')
combine (Forget x -> f r
f, Forget x' -> f r
g) = (Either x x' -> f r) -> Forget (f r) (Either x x') (Either y y')
forall k r a (b :: k). (a -> r) -> Forget r a b
Forget ((Either x x' -> f r) -> Forget (f r) (Either x x') (Either y y'))
-> (Either x x' -> f r) -> Forget (f r) (Either x x') (Either y y')
forall a b. (a -> b) -> a -> b
$ (x -> f r) -> (x' -> f r) -> Either x x' -> f r
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either x -> f r
f x' -> f r
g

instance Alternative f => Semigroupal (->) Either Either Either (Forget (f r)) where
  combine :: Either (Forget (f r) x y) (Forget (f r) x' y') -> Forget (f r) (Either x x') (Either y y')
  combine :: Either (Forget (f r) x y) (Forget (f r) x' y')
-> Forget (f r) (Either x x') (Either y y')
combine = \case
    Left (Forget x -> f r
f) -> (Either x x' -> f r) -> Forget (f r) (Either x x') (Either y y')
forall k r a (b :: k). (a -> r) -> Forget r a b
Forget ((Either x x' -> f r) -> Forget (f r) (Either x x') (Either y y'))
-> (Either x x' -> f r) -> Forget (f r) (Either x x') (Either y y')
forall a b. (a -> b) -> a -> b
$ (x -> f r) -> (x' -> f r) -> Either x x' -> f r
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either x -> f r
f (f r -> x' -> f r
forall a b. a -> b -> a
const f r
forall (f :: * -> *) a. Alternative f => f a
empty)
    Right (Forget x' -> f r
g) -> (Either x x' -> f r) -> Forget (f r) (Either x x') (Either y y')
forall k r a (b :: k). (a -> r) -> Forget r a b
Forget ((Either x x' -> f r) -> Forget (f r) (Either x x') (Either y y'))
-> (Either x x' -> f r) -> Forget (f r) (Either x x') (Either y y')
forall a b. (a -> b) -> a -> b
$ (x -> f r) -> (x' -> f r) -> Either x x' -> f r
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (f r -> x -> f r
forall a b. a -> b -> a
const f r
forall (f :: * -> *) a. Alternative f => f a
empty) x' -> f r
g

instance Alternative f => Semigroupal (->) (,) Either (,) (Forget (f r)) where
  combine :: (Forget (f r) x y, Forget (f r) x' y') -> Forget (f r) (x, x') (Either y y')
  combine :: (Forget (f r) x y, Forget (f r) x' y')
-> Forget (f r) (x, x') (Either y y')
combine (Forget x -> f r
f, Forget x' -> f r
g) = ((x, x') -> f r) -> Forget (f r) (x, x') (Either y y')
forall k r a (b :: k). (a -> r) -> Forget r a b
Forget (((x, x') -> f r) -> Forget (f r) (x, x') (Either y y'))
-> ((x, x') -> f r) -> Forget (f r) (x, x') (Either y y')
forall a b. (a -> b) -> a -> b
$ \(x
x, x'
x') -> x -> f r
f x
x f r -> f r -> f r
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> x' -> f r
g x'
x'

class Unital cat i1 i2 io f where
  introduce :: cat io (f i1 i2)

instance (Profunctor p, Category p) => Unital (->) () () () (StrongCategory p) where
  introduce :: () -> StrongCategory p () ()
  introduce :: () -> StrongCategory p () ()
introduce () = p () () -> StrongCategory p () ()
forall (p :: * -> * -> *) a b. p a b -> StrongCategory p a b
StrongCategory p () ()
forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id

instance Unital (->) () () () (,) where
  introduce :: () -> ((), ())
  introduce :: () -> ((), ())
introduce = () -> ((), ())
forall a. a -> (a, a)
dup

instance Unital (->) Void Void Void (,) where
  introduce :: Void -> (Void, Void)
  introduce :: Void -> (Void, Void)
introduce = Void -> (Void, Void)
forall a. Void -> a
absurd

instance Unital (->) Void Void Void Either where
  introduce :: Void -> Either Void Void
  introduce :: Void -> Either Void Void
introduce = Iso (->) (Either Void Void) Void -> Void -> Either Void Void
forall (cat :: * -> * -> *) a b. Iso cat a b -> cat b a
bwd Iso (->) (Either Void Void) Void
forall (t :: * -> * -> *) i (cat :: * -> * -> *) a.
Tensor t i cat =>
Iso cat (t a i) a
runit

instance Unital (->) Void () () Either where
  introduce :: () -> Either Void ()
  introduce :: () -> Either Void ()
introduce = () -> Either Void ()
forall a b. b -> Either a b
Right

instance Unital (->) () () () (->) where
  introduce :: () -> () -> ()
  introduce :: () -> () -> ()
introduce () () = ()

instance Unital (->) Void Void Void (->) where
  introduce :: Void -> Void -> Void
  introduce :: Void -> Void -> Void
introduce = Void -> Void -> Void
forall a. Void -> a
absurd

instance (Unital (->) Void Void () (->)) where
  introduce :: () -> Void -> Void
  introduce :: () -> Void -> Void
introduce () = Void -> Void
forall a. Void -> a
absurd

instance Applicative f => Unital (->) () () () (Joker f) where
  introduce :: () -> Joker f () ()
  introduce :: () -> Joker f () ()
introduce = f () -> Joker f () ()
forall k k1 (g :: k -> *) (a :: k1) (b :: k). g b -> Joker g a b
Joker (f () -> Joker f () ()) -> (() -> f ()) -> () -> Joker f () ()
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. () -> f ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure

instance Alternative f => Unital (->) Void Void () (Joker f) where
  introduce :: () -> Joker f Void Void
  introduce :: () -> Joker f Void Void
introduce () = f Void -> Joker f Void Void
forall k k1 (g :: k -> *) (a :: k1) (b :: k). g b -> Joker g a b
Joker f Void
forall (f :: * -> *) a. Alternative f => f a
empty

instance Unital (->) Void Void Void (Joker f) where
  introduce :: Void -> Joker f Void Void
  introduce :: Void -> Joker f Void Void
introduce = Void -> Joker f Void Void
forall a. Void -> a
absurd

instance Applicative f => Unital (->) () () () (Star f) where
  introduce :: () -> Star f () ()
  introduce :: () -> Star f () ()
introduce () = (() -> f ()) -> Star f () ()
forall k (f :: k -> *) d (c :: k). (d -> f c) -> Star f d c
Star () -> f ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure

instance Unital (->) Void Void () (Star f) where
  introduce :: () -> Star f Void Void
  introduce :: () -> Star f Void Void
introduce () = (Void -> f Void) -> Star f Void Void
forall k (f :: k -> *) d (c :: k). (d -> f c) -> Star f d c
Star Void -> f Void
forall a. Void -> a
absurd

instance Alternative f => Unital (->) Void Void Void (Star f) where
  introduce :: Void -> Star f Void Void
  introduce :: Void -> Star f Void Void
introduce = Void -> Star f Void Void
forall a. Void -> a
absurd

instance Alternative f => Unital (->) () Void () (Star f) where
  introduce :: () -> Star f () Void
  introduce :: () -> Star f () Void
introduce () = (() -> f Void) -> Star f () Void
forall k (f :: k -> *) d (c :: k). (d -> f c) -> Star f d c
Star ((() -> f Void) -> Star f () Void)
-> (() -> f Void) -> Star f () Void
forall a b. (a -> b) -> a -> b
$ f Void -> () -> f Void
forall a b. a -> b -> a
const f Void
forall (f :: * -> *) a. Alternative f => f a
empty

class (Tensor t1 i1 cat
      , Tensor t2 i2 cat
      , Tensor to io cat
      , Semigroupal cat t1 t2 to f
      , Unital cat i1 i2 io f
      ) => Monoidal cat t1 i1 t2 i2 to io f

instance (Strong p, Semigroupoid p, Category p) => Monoidal (->) (,) () (,) () (,) () (StrongCategory p)
instance Monoidal (->) (,) () (,) () (,) () (,)
instance Monoidal (->) Either Void Either Void Either Void (,)
instance Monoidal (->) Either Void Either Void Either Void Either
instance Monoidal (->) Either Void (,) () (,) () Either
instance Monoidal (->) These Void (,) () (,) () Either
instance Monoidal (->) (,) () (,) () (,) () (->)
instance Monoidal (->) Either Void Either Void (,) () (->)
instance Applicative f => Monoidal (->) (,) () (,) () (,) () (Joker f)
instance Alternative f => Monoidal (->) Either Void Either Void (,) () (Joker f)
instance Functor f => Monoidal (->) Either Void Either Void Either Void (Joker f)
instance Applicative f => Monoidal (->) (,) () (,) () (,) () (Star f)
instance Functor f => Monoidal (->) Either Void Either Void (,) () (Star f)
instance Alternative f => Monoidal (->) Either Void Either Void Either Void (Star f)
instance Alternative f => Monoidal (->) (,) () Either Void (,) () (Star f)

newtype StrongCategory p a b = StrongCategory (p a b)
  deriving (a -> StrongCategory p a b -> StrongCategory p a a
(a -> b) -> StrongCategory p a a -> StrongCategory p a b
(forall a b.
 (a -> b) -> StrongCategory p a a -> StrongCategory p a b)
-> (forall a b. a -> StrongCategory p a b -> StrongCategory p a a)
-> Functor (StrongCategory p a)
forall a b. a -> StrongCategory p a b -> StrongCategory p a a
forall a b.
(a -> b) -> StrongCategory p a a -> StrongCategory p a b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
forall (p :: * -> * -> *) a a b.
Functor (p a) =>
a -> StrongCategory p a b -> StrongCategory p a a
forall (p :: * -> * -> *) a a b.
Functor (p a) =>
(a -> b) -> StrongCategory p a a -> StrongCategory p a b
<$ :: a -> StrongCategory p a b -> StrongCategory p a a
$c<$ :: forall (p :: * -> * -> *) a a b.
Functor (p a) =>
a -> StrongCategory p a b -> StrongCategory p a a
fmap :: (a -> b) -> StrongCategory p a a -> StrongCategory p a b
$cfmap :: forall (p :: * -> * -> *) a a b.
Functor (p a) =>
(a -> b) -> StrongCategory p a a -> StrongCategory p a b
Functor, Functor (StrongCategory p a)
a -> StrongCategory p a a
Functor (StrongCategory p a)
-> (forall a. a -> StrongCategory p a a)
-> (forall a b.
    StrongCategory p a (a -> b)
    -> StrongCategory p a a -> StrongCategory p a b)
-> (forall a b c.
    (a -> b -> c)
    -> StrongCategory p a a
    -> StrongCategory p a b
    -> StrongCategory p a c)
-> (forall a b.
    StrongCategory p a a
    -> StrongCategory p a b -> StrongCategory p a b)
-> (forall a b.
    StrongCategory p a a
    -> StrongCategory p a b -> StrongCategory p a a)
-> Applicative (StrongCategory p a)
StrongCategory p a a
-> StrongCategory p a b -> StrongCategory p a b
StrongCategory p a a
-> StrongCategory p a b -> StrongCategory p a a
StrongCategory p a (a -> b)
-> StrongCategory p a a -> StrongCategory p a b
(a -> b -> c)
-> StrongCategory p a a
-> StrongCategory p a b
-> StrongCategory p a c
forall a. a -> StrongCategory p a a
forall a b.
StrongCategory p a a
-> StrongCategory p a b -> StrongCategory p a a
forall a b.
StrongCategory p a a
-> StrongCategory p a b -> StrongCategory p a b
forall a b.
StrongCategory p a (a -> b)
-> StrongCategory p a a -> StrongCategory p a b
forall a b c.
(a -> b -> c)
-> StrongCategory p a a
-> StrongCategory p a b
-> StrongCategory p a c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
forall (p :: * -> * -> *) a.
Applicative (p a) =>
Functor (StrongCategory p a)
forall (p :: * -> * -> *) a a.
Applicative (p a) =>
a -> StrongCategory p a a
forall (p :: * -> * -> *) a a b.
Applicative (p a) =>
StrongCategory p a a
-> StrongCategory p a b -> StrongCategory p a a
forall (p :: * -> * -> *) a a b.
Applicative (p a) =>
StrongCategory p a a
-> StrongCategory p a b -> StrongCategory p a b
forall (p :: * -> * -> *) a a b.
Applicative (p a) =>
StrongCategory p a (a -> b)
-> StrongCategory p a a -> StrongCategory p a b
forall (p :: * -> * -> *) a a b c.
Applicative (p a) =>
(a -> b -> c)
-> StrongCategory p a a
-> StrongCategory p a b
-> StrongCategory p a c
<* :: StrongCategory p a a
-> StrongCategory p a b -> StrongCategory p a a
$c<* :: forall (p :: * -> * -> *) a a b.
Applicative (p a) =>
StrongCategory p a a
-> StrongCategory p a b -> StrongCategory p a a
*> :: StrongCategory p a a
-> StrongCategory p a b -> StrongCategory p a b
$c*> :: forall (p :: * -> * -> *) a a b.
Applicative (p a) =>
StrongCategory p a a
-> StrongCategory p a b -> StrongCategory p a b
liftA2 :: (a -> b -> c)
-> StrongCategory p a a
-> StrongCategory p a b
-> StrongCategory p a c
$cliftA2 :: forall (p :: * -> * -> *) a a b c.
Applicative (p a) =>
(a -> b -> c)
-> StrongCategory p a a
-> StrongCategory p a b
-> StrongCategory p a c
<*> :: StrongCategory p a (a -> b)
-> StrongCategory p a a -> StrongCategory p a b
$c<*> :: forall (p :: * -> * -> *) a a b.
Applicative (p a) =>
StrongCategory p a (a -> b)
-> StrongCategory p a a -> StrongCategory p a b
pure :: a -> StrongCategory p a a
$cpure :: forall (p :: * -> * -> *) a a.
Applicative (p a) =>
a -> StrongCategory p a a
$cp1Applicative :: forall (p :: * -> * -> *) a.
Applicative (p a) =>
Functor (StrongCategory p a)
Applicative, Applicative (StrongCategory p a)
a -> StrongCategory p a a
Applicative (StrongCategory p a)
-> (forall a b.
    StrongCategory p a a
    -> (a -> StrongCategory p a b) -> StrongCategory p a b)
-> (forall a b.
    StrongCategory p a a
    -> StrongCategory p a b -> StrongCategory p a b)
-> (forall a. a -> StrongCategory p a a)
-> Monad (StrongCategory p a)
StrongCategory p a a
-> (a -> StrongCategory p a b) -> StrongCategory p a b
StrongCategory p a a
-> StrongCategory p a b -> StrongCategory p a b
forall a. a -> StrongCategory p a a
forall a b.
StrongCategory p a a
-> StrongCategory p a b -> StrongCategory p a b
forall a b.
StrongCategory p a a
-> (a -> StrongCategory p a b) -> StrongCategory p a b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
forall (p :: * -> * -> *) a.
Monad (p a) =>
Applicative (StrongCategory p a)
forall (p :: * -> * -> *) a a.
Monad (p a) =>
a -> StrongCategory p a a
forall (p :: * -> * -> *) a a b.
Monad (p a) =>
StrongCategory p a a
-> StrongCategory p a b -> StrongCategory p a b
forall (p :: * -> * -> *) a a b.
Monad (p a) =>
StrongCategory p a a
-> (a -> StrongCategory p a b) -> StrongCategory p a b
return :: a -> StrongCategory p a a
$creturn :: forall (p :: * -> * -> *) a a.
Monad (p a) =>
a -> StrongCategory p a a
>> :: StrongCategory p a a
-> StrongCategory p a b -> StrongCategory p a b
$c>> :: forall (p :: * -> * -> *) a a b.
Monad (p a) =>
StrongCategory p a a
-> StrongCategory p a b -> StrongCategory p a b
>>= :: StrongCategory p a a
-> (a -> StrongCategory p a b) -> StrongCategory p a b
$c>>= :: forall (p :: * -> * -> *) a a b.
Monad (p a) =>
StrongCategory p a a
-> (a -> StrongCategory p a b) -> StrongCategory p a b
$cp1Monad :: forall (p :: * -> * -> *) a.
Monad (p a) =>
Applicative (StrongCategory p a)
Monad, q b c -> StrongCategory p a b -> StrongCategory p a c
StrongCategory p b c -> q a b -> StrongCategory p a c
(a -> b)
-> (c -> d) -> StrongCategory p b c -> StrongCategory p a d
(a -> b) -> StrongCategory p b c -> StrongCategory p a c
(b -> c) -> StrongCategory p a b -> StrongCategory p a c
(forall a b c d.
 (a -> b)
 -> (c -> d) -> StrongCategory p b c -> StrongCategory p a d)
-> (forall a b c.
    (a -> b) -> StrongCategory p b c -> StrongCategory p a c)
-> (forall b c a.
    (b -> c) -> StrongCategory p a b -> StrongCategory p a c)
-> (forall a b c (q :: * -> * -> *).
    Coercible c b =>
    q b c -> StrongCategory p a b -> StrongCategory p a c)
-> (forall a b c (q :: * -> * -> *).
    Coercible b a =>
    StrongCategory p b c -> q a b -> StrongCategory p a c)
-> Profunctor (StrongCategory p)
forall a b c.
(a -> b) -> StrongCategory p b c -> StrongCategory p a c
forall b c a.
(b -> c) -> StrongCategory p a b -> StrongCategory p a c
forall a b c d.
(a -> b)
-> (c -> d) -> StrongCategory p b c -> StrongCategory p a d
forall a b c (q :: * -> * -> *).
Coercible b a =>
StrongCategory p b c -> q a b -> StrongCategory p a c
forall a b c (q :: * -> * -> *).
Coercible c b =>
q b c -> StrongCategory p a b -> StrongCategory p a c
forall (p :: * -> * -> *) a b c.
Profunctor p =>
(a -> b) -> StrongCategory p b c -> StrongCategory p a c
forall (p :: * -> * -> *) b c a.
Profunctor p =>
(b -> c) -> StrongCategory p a b -> StrongCategory p a c
forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b)
-> (c -> d) -> StrongCategory p b c -> StrongCategory p a d
forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
(Profunctor p, Coercible b a) =>
StrongCategory p b c -> q a b -> StrongCategory p a c
forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
(Profunctor p, Coercible c b) =>
q b c -> StrongCategory p a b -> StrongCategory p a c
forall (p :: * -> * -> *).
(forall a b c d. (a -> b) -> (c -> d) -> p b c -> p a d)
-> (forall a b c. (a -> b) -> p b c -> p a c)
-> (forall b c a. (b -> c) -> p a b -> p a c)
-> (forall a b c (q :: * -> * -> *).
    Coercible c b =>
    q b c -> p a b -> p a c)
-> (forall a b c (q :: * -> * -> *).
    Coercible b a =>
    p b c -> q a b -> p a c)
-> Profunctor p
.# :: StrongCategory p b c -> q a b -> StrongCategory p a c
$c.# :: forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
(Profunctor p, Coercible b a) =>
StrongCategory p b c -> q a b -> StrongCategory p a c
#. :: q b c -> StrongCategory p a b -> StrongCategory p a c
$c#. :: forall (p :: * -> * -> *) a b c (q :: * -> * -> *).
(Profunctor p, Coercible c b) =>
q b c -> StrongCategory p a b -> StrongCategory p a c
rmap :: (b -> c) -> StrongCategory p a b -> StrongCategory p a c
$crmap :: forall (p :: * -> * -> *) b c a.
Profunctor p =>
(b -> c) -> StrongCategory p a b -> StrongCategory p a c
lmap :: (a -> b) -> StrongCategory p b c -> StrongCategory p a c
$clmap :: forall (p :: * -> * -> *) a b c.
Profunctor p =>
(a -> b) -> StrongCategory p b c -> StrongCategory p a c
dimap :: (a -> b)
-> (c -> d) -> StrongCategory p b c -> StrongCategory p a d
$cdimap :: forall (p :: * -> * -> *) a b c d.
Profunctor p =>
(a -> b)
-> (c -> d) -> StrongCategory p b c -> StrongCategory p a d
Profunctor, StrongCategory p a a
StrongCategory p b c
-> StrongCategory p a b -> StrongCategory p a c
(forall a. StrongCategory p a a)
-> (forall b c a.
    StrongCategory p b c
    -> StrongCategory p a b -> StrongCategory p a c)
-> Category (StrongCategory p)
forall a. StrongCategory p a a
forall b c a.
StrongCategory p b c
-> StrongCategory p a b -> StrongCategory p a c
forall k (cat :: k -> k -> *).
(forall (a :: k). cat a a)
-> (forall (b :: k) (c :: k) (a :: k).
    cat b c -> cat a b -> cat a c)
-> Category cat
forall (p :: * -> * -> *) a. Category p => StrongCategory p a a
forall (p :: * -> * -> *) b c a.
Category p =>
StrongCategory p b c
-> StrongCategory p a b -> StrongCategory p a c
. :: StrongCategory p b c
-> StrongCategory p a b -> StrongCategory p a c
$c. :: forall (p :: * -> * -> *) b c a.
Category p =>
StrongCategory p b c
-> StrongCategory p a b -> StrongCategory p a c
id :: StrongCategory p a a
$cid :: forall (p :: * -> * -> *) a. Category p => StrongCategory p a a
Category)

instance Semigroupoid p => Semigroupoid (StrongCategory p) where
  o :: StrongCategory p b c -> StrongCategory p a b -> StrongCategory p a c
  o :: StrongCategory p b c
-> StrongCategory p a b -> StrongCategory p a c
o (StrongCategory p b c
f) (StrongCategory p a b
g) = p a c -> StrongCategory p a c
forall (p :: * -> * -> *) a b. p a b -> StrongCategory p a b
StrongCategory (p b c
f p b c -> p a b -> p a c
forall k (c :: k -> k -> *) (j :: k) (k1 :: k) (i :: k).
Semigroupoid c =>
c j k1 -> c i j -> c i k1
`o` p a b
g)

instance (Strong p, Semigroupoid p) => Semigroupal (->) (,) (,) (,) (StrongCategory p) where
  combine :: (StrongCategory p x y, StrongCategory p x' y') -> StrongCategory p (x, x') (y, y')
  combine :: (StrongCategory p x y, StrongCategory p x' y')
-> StrongCategory p (x, x') (y, y')
combine (StrongCategory p x y
pxy, StrongCategory p x' y'
pxy') = p (x, x') (y, y') -> StrongCategory p (x, x') (y, y')
forall (p :: * -> * -> *) a b. p a b -> StrongCategory p a b
StrongCategory (p (x, x') (y, y') -> StrongCategory p (x, x') (y, y'))
-> p (x, x') (y, y') -> StrongCategory p (x, x') (y, y')
forall a b. (a -> b) -> a -> b
$ p x y -> p (x, y') (y, y')
forall (p :: * -> * -> *) a b c.
Strong p =>
p a b -> p (a, c) (b, c)
first' p x y
pxy p (x, y') (y, y') -> p (x, x') (x, y') -> p (x, x') (y, y')
forall k (c :: k -> k -> *) (j :: k) (k1 :: k) (i :: k).
Semigroupoid c =>
c j k1 -> c i j -> c i k1
`o` p x' y' -> p (x, x') (x, y')
forall (p :: * -> * -> *) a b c.
Strong p =>
p a b -> p (c, a) (c, b)
second' p x' y'
pxy'