{-# LANGUAGE TypeFamilies, GADTs, RankNTypes, TypeOperators, UndecidableInstances, NoImplicitPrelude #-}
module Data.Category.Cube where
import Data.Category
import Data.Category.Product
import Data.Category.Functor
import Data.Category.Monoidal
import Data.Category.Limit
data Z
data S n
data Sign = M | P
data Cube :: * -> * -> * where
Z :: Cube Z Z
S :: Cube x y -> Cube (S x) (S y)
Y :: Sign -> Cube x y -> Cube x (S y)
X :: Cube x y -> Cube (S x) y
instance Category Cube where
src Z = Z
src (S c) = S (src c)
src (Y _ c) = src c
src (X c) = S (src c)
tgt Z = Z
tgt (S c) = S (tgt c)
tgt (Y _ c) = S (tgt c)
tgt (X c) = tgt c
Z . c = c
c . Z = c
S c . S d = S (c . d)
S c . Y s d = Y s (c . d)
Y s c . d = Y s (c . d)
X c . S d = X (c . d)
X c . Y _ d = c . d
c . X d = X (c . d)
instance HasTerminalObject Cube where
type TerminalObject Cube = Z
terminalObject = Z
terminate Z = Z
terminate (S f) = X (terminate f)
data Sign0 = SM | S0 | SP
data ACube :: * -> * where
Nil :: ACube Z
Cons :: Sign0 -> ACube n -> ACube (S n)
data Forget = Forget
instance Functor Forget where
type Dom Forget = Cube
type Cod Forget = (->)
type Forget :% n = ACube n
Forget % Z = \x -> x
Forget % S f = \(Cons s x) -> Cons s ((Forget % f) x)
Forget % Y M f = \x -> Cons SM ((Forget % f) x)
Forget % Y P f = \x -> Cons SP ((Forget % f) x)
Forget % X f = \(Cons _ x) -> (Forget % f) x
data Add = Add
instance Functor Add where
type Dom Add = Cube :**: Cube
type Cod Add = Cube
type Add :% (Z , n) = n
type Add :% (S m, n) = S (Add :% (m, n))
Add % (Z :**: g) = g
Add % (S f :**: g) = S (Add % (f :**: g))
Add % (Y s f :**: g) = Y s (Add % (f :**: g))
Add % (X f :**: g) = X (Add % (f :**: g))
instance TensorProduct Add where
type Unit Add = Z
unitObject Add = Z
leftUnitor Add a = a
leftUnitorInv Add a = a
rightUnitor Add Z = Z
rightUnitor Add (S n) = S (rightUnitor Add n)
rightUnitorInv Add Z = Z
rightUnitorInv Add (S n) = S (rightUnitorInv Add n)
associator Add Z Z n = n
associator Add Z (S m) n = S (associator Add Z m n)
associator Add (S l) m n = S (associator Add l m n)
associatorInv Add Z Z n = n
associatorInv Add Z (S m) n = S (associatorInv Add Z m n)
associatorInv Add (S l) m n = S (associatorInv Add l m n)