proarrow-0.1.0.0: src/Proarrow/Category/Instance/IntConstruction.hs
-- | The __Int construction__ (Joyal-Street-Verity) on a traced monoidal category @k@: objects are
-- formal differences @'I' plus minus@ of @k@-objects, and morphisms are @k@-morphisms between the
-- appropriately tensored halves, composed by tracing out the middle. The result is compact closed
-- (the free such over @k@) with duals given by swapping the two halves.
module Proarrow.Category.Instance.IntConstruction where
import Prelude (($), type (~))
import Proarrow.Category.Monoidal
( Monoidal (..)
, MonoidalProfunctor (..)
, SymMonoidal (..)
, obj2
, swap
, swapFst
, swapInner
, swapOuter
, (**)
)
import Proarrow.Category.Monoidal.Closed (Closed (..))
import Proarrow.Category.Monoidal.CompactClosed (CompactClosed (..))
import Proarrow.Category.Monoidal.StarAutonomous (ExpSA, StarAutonomous (..), applySA, currySA, expSA)
import Proarrow.Category.Monoidal.Strength (TracedMonoidal, trace)
import Proarrow.Core (CAT, CategoryOf (..), Profunctor (..), Promonad (..), dimapDefault, obj)
data INT k = I k k
type family IntPlus (i :: INT k) :: k where
IntPlus (I a b) = a
type family IntMinus (i :: INT k) :: k where
IntMinus (I a b) = b
type IntConstruction :: CAT (INT k)
data IntConstruction a b where
Int :: (Ob ap, Ob am, Ob bp, Ob bm) => ap ** bm ~> am ** bp -> IntConstruction (I ap am) (I bp bm)
toInt :: forall {k} (a :: k) b m. (TracedMonoidal k, Ob m) => (a ~> b) -> I a m ~> I b m
toInt f = Int (swap @k @b @m . (f ** obj @m)) \\ f
isoToInt :: forall {k} (a :: k) b. (TracedMonoidal k) => (a ~> b) -> (b ~> a) -> I a a ~> I b b
isoToInt f g = Int (swap @k @b @a . (f ** g)) \\ f \\ g
fromInt :: forall {k} (a :: k) b m. (TracedMonoidal k) => (I a m ~> I b m) -> a ~> b
fromInt (Int f) = trace @(~>) @m @a @b (swap @k @m @b . f)
instance (TracedMonoidal k) => Profunctor (IntConstruction :: CAT (INT k)) where
dimap = dimapDefault
r \\ Int{} = r
instance (TracedMonoidal k) => Promonad (IntConstruction :: CAT (INT k)) where
id @a = Int (swap @k @(IntPlus a) @(IntMinus a))
Int @bp @bm @cp @cm f . Int @ap @am g =
Int
( trace @_ @(bp ** bm) @(ap ** cm) @(am ** cp)
(swapOuter @bm @cp @bp @am . (f ** (swap @k @am @bp . g)) . swapFst @ap @cm @bp @bm)
)
\\ obj2 @ap @cm
\\ obj2 @am @cp
\\ obj2 @bp @bm
-- | The Int construction, a.k.a. the geometry of interaction,
-- the free compact closed category on a traced monoidal category.
instance (TracedMonoidal k) => CategoryOf (INT k) where
type (~>) = IntConstruction
type Ob a = (a ~ I (IntPlus a) (IntMinus a), Ob (IntPlus a), Ob (IntMinus a))
instance (TracedMonoidal k) => MonoidalProfunctor (IntConstruction :: CAT (INT k)) where
one = Int (swap @k @Unit @Unit)
Int @ap @am @bp @bm f ** Int @cp @cm @dp @dm g =
Int (swapInner @am @bp @cm @dp . (f ** g) . swapInner @ap @cp @bm @dm)
\\ obj2 @(I ap am) @(I cp cm)
\\ obj2 @(I bp bm) @(I dp dm)
-- | The monoidal tensor is pointwise, tensoring of the plus and minus parts.
instance (TracedMonoidal k) => Monoidal (INT k) where
type Unit = I Unit Unit
type a ** b = I (IntPlus a ** IntPlus b) (IntMinus a ** IntMinus b)
withOb2 @a @b r = withOb2 @k @(IntPlus a) @(IntPlus b) (withOb2 @k @(IntMinus a) @(IntMinus b) r)
leftUnitor @(I ap am) =
Int ((leftUnitorInv @k @am ** obj @ap) . swap @k @ap @am . (leftUnitor @k @ap ** obj @am))
\\ obj2 @Unit @ap
\\ obj2 @Unit @am
leftUnitorInv @(I ap am) =
Int ((obj @am ** leftUnitorInv @k @ap) . swap @k @ap @am . (obj @ap ** leftUnitor @k @am))
\\ obj2 @Unit @ap
\\ obj2 @Unit @am
rightUnitor @(I ap am) =
Int ((rightUnitorInv @k @am ** obj @ap) . swap @k @ap @am . (rightUnitor @k @ap ** obj @am))
\\ obj2 @ap @Unit
\\ obj2 @am @Unit
rightUnitorInv @(I ap am) =
Int ((obj @am ** rightUnitorInv @k @ap) . swap @k @ap @am . (obj @ap ** rightUnitor @k @am))
\\ obj2 @ap @Unit
\\ obj2 @am @Unit
associator @(I ap am) @(I bp bm) @(I cp cm) =
Int (swap @k @(ap ** (bp ** cp)) @((am ** bm) ** cm) . (associator @k @ap @bp @cp ** associatorInv @k @am @bm @cm))
\\ obj2 @(I ap am) @(I bp bm) ** obj @(I cp cm)
\\ obj @(I ap am) ** obj2 @(I bp bm) @(I cp cm)
associatorInv @(I ap am) @(I bp bm) @(I cp cm) =
Int (swap @k @((ap ** bp) ** cp) @(am ** (bm ** cm)) . (associatorInv @k @ap @bp @cp ** associator @k @am @bm @cm))
\\ obj2 @(I ap am) @(I bp bm) ** obj @(I cp cm)
\\ obj @(I ap am) ** obj2 @(I bp bm) @(I cp cm)
instance (TracedMonoidal k) => SymMonoidal (INT k) where
swap @(I ap am) @(I bp bm) =
withOb2 @k @ap @bp $
withOb2 @k @am @bm $
withOb2 @k @bp @ap $
withOb2 @k @bm @am $
Int ((swap @k @bm @am ** swap @k @ap @bp) . swap @k @(ap ** bp) @(bm ** am))
instance (TracedMonoidal k) => Closed (INT k) where
type a ~~> b = ExpSA a b
withObExp @a @b r = withOb2 @k @(IntMinus a) @(IntPlus b) (withOb2 @k @(IntPlus a) @(IntMinus b) r)
curry @a @b @c = currySA @a @b @c
apply @b @c = applySA @b @c
(^^^) = expSA
instance (TracedMonoidal k) => StarAutonomous (INT k) where
type Dual (I p n) = I n p
withObDual r = r
dual (Int @ap @am @bp @bm f) = Int (swap @k @am @bp . f . swap @k @bm @ap)
dualInv (Int @ap @am @bp @bm f) = Int (swap @k @am @bp . f . swap @k @bm @ap)
linDist @(I ap am) @(I bp bm) @(I cp cm) (Int f) = Int (associator @k @am @bm @cm . f . associatorInv @k @ap @bp @cp) \\ obj2 @(I bp bm) @(I cp cm)
linDistInv @(I ap am) @(I bp bm) @(I cp cm) (Int f) = Int (associatorInv @k @am @bm @cm . f . associator @k @ap @bp @cp) \\ obj2 @(I ap am) @(I bp bm)
doubleNeg = id
doubleNegInv = id
instance (TracedMonoidal k) => CompactClosed (INT k) where
distribDual @(I ap am) @(I bp bm) = Int (swap @k @(am ** bm) @(ap ** bp)) \\ obj2 @(I ap am) @(I bp bm)
dualUnit = id
dualityUnit @(I p n) =
withOb2 @k @p @n $ withOb2 @k @n @p $ Int (leftUnitorInv @k @(p ** n) . swap @k @n @p . leftUnitor @k @(n ** p))
dualityCounit @(I p n) =
withOb2 @k @p @n $ withOb2 @k @n @p $ Int (rightUnitorInv @k @(p ** n) . swap @k @n @p . rightUnitor @k @(n ** p))