linear-smc-2.0.1: Control/Category/FreeCartesian.hs
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# OPTIONS_GHC -Wno-incomplete-patterns -Wno-overlapping-patterns #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE TypeInType #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE LinearTypes #-}
module Control.Category.FreeCartesian where
import Prelude hiding ((.),id,curry)
import Control.Category.Constrained
import Data.Kind
instance (forall x y. (con x, con y) => Show (k x y)) => Show (Cat k con a b) where
show x = showsPrec (-1) x ""
showsPrec d = \case
I -> showString "id"
P1 -> showString "π₁"
P2 -> showString "π₂"
Embed s -> showString (show s)
f :.: g -> showParen (d > 0) (showsPrec 0 f . showString " ∘ " . showsPrec 0 g)
f :▵: g -> showParen (d > -1) (showsPrec 2 f . showString " ▵ " . showsPrec 2 g)
showDbg :: Int -> Cat k con a b -> ShowS
showDbg d = \case
Embed _ -> showString "?"
I -> showString "id"
f :.: g -> showParen (d /= 0) (showDbg 0 f . showString " ∘ " . showDbg 0 g)
f :▵: g -> showParen True (showDbg 2 f . showString " ▵ " . showDbg 2 g)
P2 -> showString "π₂"
P1 -> showString "π₁"
parens :: [Char] -> [Char]
parens x = "(" <> x <> ")"
mapGenerators :: (con a, con b) => (forall x y. (con x, con y) => k x y -> k' x y) -> Cat k con a b -> Cat k' con a b
mapGenerators f = \case
I -> I
Embed g -> Embed (f g)
a :.: b -> mapGenerators f a :.: mapGenerators f b
P1 -> P1
P2 -> P2
a :▵: b -> mapGenerators f a :▵: mapGenerators f b
x -> error (showDbg 0 x " (Free.mapGenerators)")
type Cat = FreeCartesian
data FreeCartesian k {-<-} (con :: Type -> Constraint) {->-} a b where
I :: FreeCartesian k {-<-}con{->-} a a
(:.:) :: {-<-}con b => {->-} FreeCartesian k {-<-}con{->-} b c -> FreeCartesian k {-<-}con{->-} a b
-> FreeCartesian k {-<-}con{->-} a c
Embed :: {-<-}(con a, con b) => {->-}k a b -> FreeCartesian k {-<-}con{->-} a b
(:▵:) :: {-<-}(con a, con b, con c) => {->-}FreeCartesian k {-<-}con {->-}a b -> FreeCartesian k {-<-}con{->-} a c
-> FreeCartesian k {-<-}con{->-} a (b ⊗ c)
P1 :: {-<-}con b => {->-} FreeCartesian k {-<-}con{->-} (a ⊗ b) a
P2 :: {-<-}con a => {->-} FreeCartesian k {-<-}con{->-} (a ⊗ b) b {-<-}
assocRight :: (Cat k obj x y) -> (Cat k obj x y)
assocRight (a :.: (assocRight -> (b :.: c))) = (a :.: b) :.: c
assocRight x = x
rightView :: (obj a, obj c) => (Cat k obj a c) -> Cat k obj a c
rightView (assocRight -> (a :.: b)) = a :.: b
rightView x = I :.: x
assocLeft :: (Cat k obj x y) -> (Cat k obj x y)
assocLeft ((assocLeft -> (a :.: b)) :.: c) = a :.: (b :.: c)
assocLeft x = x
leftView :: (obj a, obj c) => (Cat k obj a c) -> Cat k obj a c
leftView (assocLeft -> (a :.: b)) = a :.: b
leftView x = x :.: I
pattern (:>:) :: (obj x, obj y) => (obj b) => Cat k obj b y -> Cat k obj x b -> Cat k obj x y
pattern f :>: g <- (rightView -> f :.: g)
where f :>: g = f . g
pattern (:<:) :: (obj x, obj y) => (obj b) => (Cat k obj b y) -> (Cat k obj x b) -> Cat k obj x y
pattern f :<: g <- (leftView -> f :.: g)
where f :<: g = f . g
evalCartesian :: forall k a b con f.
(ProdObj con, forall x y. (con x, con y) => con (x,y), con (),
con ~ Obj k, Obj k a, Obj k b, Cartesian f, Obj f ~ con) =>
(forall α β. (con α, con β) => k α β -> f α β) ->
Cat k (Obj k) a b -> f a b
evalCartesian embed = \case
I -> id
(f :.: g) -> evalCartesian embed f . evalCartesian embed g
(Embed φ) -> embed φ
P1 -> exl
P2 -> exr
f :▵: g -> evalCartesian embed f ▵ evalCartesian embed g
instance Category (Cat k con) where
type Obj (Cat k con) = con
id = I
I ∘ x = x
x ∘ I = x
P1 ∘ (f :▵: _) = f
P2 ∘ (_ :▵: g) = g
x ∘ y = x :.: y
instance ({-<-}ProdObj con, con (), forall a b. (con a, con b) => con (a,b), {->-}Monoidal k) => Monoidal (FreeCartesian k {-<-}con{->-}) {-<-}where
f × g = cartesianCross f g
assoc = cartesianAssoc
assoc' = cartesianAssoc'
swap = cartesianSwap
unitor = cartesianUnitor
unitor' = cartesianUnitor'{->-}
instance ({-<-}ProdObj con, con (), forall a b. (con a, con b) => con (a,b),{->-} Monoidal k) => Cartesian (FreeCartesian k {-<-}con{->-}) {-<-}where
exl = P1
exr = P2
dup = id :▵: id
(▵) = (:▵:){->-}