proarrow-0.1.0.0: src/Proarrow/Category/Instance/Span.hs
-- | The category of __spans__ in @k@: objects are those of @k@ (wrapped in 'SP'), and a morphism
-- @a '~>' b@ is a span @a <- x -> b@, composed by pullback. With the product of @k@ as tensor every
-- object is a Frobenius monoid, giving the hypergraph\/dagger structure dual to
-- "Proarrow.Category.Instance.Cospan".
module Proarrow.Category.Instance.Span where
import Proarrow.Category.Enriched.Dagger (DaggerProfunctor (..))
import Proarrow.Category.Monoidal (Monoidal (..), MonoidalProfunctor (..), SymMonoidal (..))
import Proarrow.Category.Monoidal.Closed (Closed (..))
import Proarrow.Category.Monoidal.CompactClosed (CompactClosed (..))
import Proarrow.Category.Monoidal.CopyDiscard (CopyDiscard)
import Proarrow.Category.Monoidal.Hypergraph (ExpHG, Frobenius, Hypergraph, applyHG, cap, cup, curryHG)
import Proarrow.Category.Monoidal.StarAutonomous (StarAutonomous (..))
import Proarrow.Core (CAT, CategoryOf (..), Profunctor (..), Promonad (..), WrappedOb, dimapDefault, src)
import Proarrow.Limit.BinaryProduct
( HasBinaryProducts (..)
, HasProducts
, associatorProd
, associatorProdInv
, leftUnitorProd
, leftUnitorProdInv
, rightUnitorProd
, rightUnitorProdInv
, swapProd
)
import Proarrow.Limit.Pullback (HasPullbacks (..))
import Proarrow.Limit.Terminal (HasTerminalObject (..))
import Proarrow.Monoid (CocommutativeComonoid, CommutativeMonoid, Comonoid (..), Monoid (..))
type data SPAN k = SP k
type Span :: CAT (SPAN k)
data Span a b where
Span :: forall c a b. c ~> a -> c ~> b -> Span (SP a) (SP b)
arr :: (CategoryOf k) => (a :: k) ~> b -> Span (SP a) (SP b)
arr f = Span (src f) f
coarr :: (CategoryOf k) => (a :: k) ~> b -> Span (SP b) (SP a)
coarr f = Span f (src f)
instance (HasPullbacks k) => Profunctor (Span :: CAT (SPAN k)) where
dimap = dimapDefault
r \\ Span f g = r \\ f \\ g
instance (HasPullbacks k) => Promonad (Span :: CAT (SPAN k)) where
id = Span id id
Span f g . Span h i = pullback i f \l r -> Span (h . l) (g . r)
-- | The category of spans in @k@: an arrow @'SP' a '~>' 'SP' b@ is a pair of arrows @x '~>' a@
-- and @x '~>' b@ out of a common object, and composition glues along a pullback.
instance (HasPullbacks k) => CategoryOf (SPAN k) where
type (~>) = Span
type Ob a = WrappedOb SP a
instance (HasPullbacks k, HasProducts k) => MonoidalProfunctor (Span :: CAT (SPAN k)) where
one = id
Span l1 l2 ** Span r1 r2 = Span (l1 *** r1) (l2 *** r2)
instance (HasPullbacks k, HasProducts k) => Monoidal (SPAN k) where
type SP a ** SP b = SP (a && b)
type Unit = SP TerminalObject
withOb2 @(SP a) @(SP b) r = withObProd @k @a @b r
leftUnitor = arr leftUnitorProd
leftUnitorInv = arr leftUnitorProdInv
rightUnitor = arr rightUnitorProd
rightUnitorInv = arr rightUnitorProdInv
associator @(SP a) @(SP b) @(SP c) = arr (associatorProd @a @b @c)
associatorInv @(SP a) @(SP b) @(SP c) = arr (associatorProdInv @a @b @c)
instance (HasPullbacks k, HasProducts k) => SymMonoidal (SPAN k) where
swap @(SP a) @(SP b) = arr (swapProd @a @b)
instance (HasPullbacks k, HasProducts k, Ob a) => Monoid (SP (a :: k)) where
mempty = coarr terminate
mappend = coarr (id &&& id)
instance (HasPullbacks k, HasProducts k, Ob a) => CommutativeMonoid (SP (a :: k))
instance (HasPullbacks k, HasProducts k, Ob a) => Comonoid (SP (a :: k)) where
counit = arr terminate
comult = arr (id &&& id)
instance (HasPullbacks k, HasProducts k, Ob a) => CocommutativeComonoid (SP (a :: k))
instance (HasPullbacks k, HasProducts k, Ob a) => Frobenius (SP (a :: k))
instance (HasPullbacks k, HasProducts k) => Hypergraph (SPAN k)
instance (HasPullbacks k, HasProducts k) => CopyDiscard (SPAN k)
instance (HasPullbacks k, HasProducts k) => Closed (SPAN k) where
type a ~~> b = ExpHG a b
withObExp @(SP a) @(SP b) r = withObProd @k @a @b r
curry @a @b = curryHG @a @b
apply @b @c = applyHG @b @c
instance (HasPullbacks k, HasProducts k) => StarAutonomous (SPAN k) where
type Dual a = a
withObDual r = r
dual (Span f g) = Span g f
dualInv (Span f g) = Span g f
linDist @(SP a) @(SP b) (Span f g) = Span (fst @k @a @b . f) (snd @k @a @b . f &&& g)
linDistInv @_ @(SP b) @(SP c) (Span f g) = Span (f &&& fst @k @b @c . g) (snd @k @b @c . g)
doubleNeg = id
doubleNegInv = id
instance (HasPullbacks k, HasProducts k) => CompactClosed (SPAN k) where
distribDual @(SP a) @(SP b) = withObProd @k @a @b id
dualUnit = id
dualityUnit @a = cup @a
dualityCounit @a = cap @a
instance (HasPullbacks k, HasProducts k) => DaggerProfunctor (Span :: CAT (SPAN k)) where
dagger = dual
-- Spans over @k@ do /not/ inherit binary products, coproducts or biproducts from @k@'s
-- coproducts alone. That construction is valid only when @k@ is extensive (its coproducts
-- disjoint and stable under pullback), which 'HasPullbacks' plus 'HasBinaryCoproducts' does not
-- imply. Over BOOL, which satisfies both, @snd . (s &&& t)@ collapses to @s@ where the product
-- law demands @t@. The instances are therefore omitted; the monoidal, compact-closed and
-- hypergraph structure above needs no such condition and is unaffected.