3 | module Control.Category.Instances.Linear
5 | import Control.Category
6 | import Control.Category.Records
7 | import Control.Category.Instances.Type
8 | import public Data.Linear
9 | import Data.Linear.LEither
10 | import Data.Linear.LMaybe
12 | import Data.List.Quantifiers
13 | import Data.Morphisms
20 | data Linear : (a,b : Type0) -> Type where
21 | MkLinear : (1 _ : a.runW0 -@ b.runW0) -> Linear a b
23 | public export %inline %tcinline
24 | runLinear : Linear a b -@ a.runW0 -@ b.runW0
25 | runLinear (MkLinear f) = f
27 | public export %inline %tcinline
28 | (.runLinear) : Linear a b -@ a.runW0 -@ b.runW0
29 | (.runLinear) = runLinear
31 | public export %inline
32 | Linear_ : (0 a,b : Type) -> Type
33 | Linear_ a b = Linear (W0 a) (W0 b)
37 | LPair : Type0 -> Type0 -> Type0
38 | LPair = liftW2 LPair
41 | LEither : Type0 -> Type0 -> Type0
42 | LEither = liftW2 LEither
45 | LinearHom : Type0 -> Type0 -> Type0
46 | LinearHom a b = W0 (Linear a b)
50 | leither : a -@ c -> b -@ c -> LEither a b -@ c
51 | leither f g (Left x) = f x
52 | leither f g (Right y) = g y
60 | Category Linear where
62 | MkLinear f . MkLinear g = MkLinear (f . g)
65 | LinearSemigroupoid : Semigroupoid Linear
66 | LinearSemigroupoid = FromCategory
70 | CatFunctor Linear Typ Prelude.id where
71 | map (MkLinear f) = MkTyp $
\x => f x
74 | LaxMonFunctor Linear LPair (W0 ()) Typ Pair (W0 ()) Prelude.id where
76 | fjoin = MkTyp $
\(x,y) => x # y
79 | MonFunctor Linear LPair (W0 ()) Typ Pair (W0 ()) Prelude.id where
81 | fjoin' = MkTyp $
\(x # y) => (x,y)
91 | CatFunctor Linear Linear (liftW LMaybe) where
92 | map (MkLinear f) = MkLinear $
(<$>) f
95 | CatBifunctor Linear Linear Linear LPair where
96 | bimap (MkLinear f) (MkLinear g) = MkLinear (\(x # y) => f x # g y)
99 | CatBifunctor Linear Linear Linear LEither where
100 | bimap (MkLinear f) (MkLinear g) = MkLinear (leither (Left . f) (Right . g))
103 | Monoidal Linear LPair (W0 ()) where
104 | assoc = MkLinear $
\((x # y) # z) => x # (y # z)
105 | assoc' = MkLinear $
\(x # (y # z)) => (x # y) # z
106 | unitl = MkLinear $
\(() # x) => x
107 | unitl' = MkLinear (() #)
108 | unitr = MkLinear $
\(x # ()) => x
109 | unitr' = MkLinear (# ())
112 | Monoidal Linear LEither (W0 Void) where
113 | assoc = MkLinear $
leither (leither Left (Right . Left)) (Right . Right)
114 | assoc' = MkLinear $
leither (Left . Left) (leither (Left . Right) Right)
115 | unitl = MkLinear $
leither (\_ impossible) id
116 | unitl' = MkLinear Right
117 | unitr = MkLinear $
leither id (\_ impossible)
118 | unitr' = MkLinear Left
121 | Braided Linear LPair (W0 ()) where
122 | braid = MkLinear $
\(x # y) => y # x
125 | Braided Linear LEither (W0 Void) where
126 | braid = MkLinear $
leither Right Left
129 | MonSymmetric Linear LPair (W0 ()) where
130 | permute {xs=[]} [] = id
131 | permute {xs=[_]} [_] = id
132 | permute p = MkLinear $
assert_linear $
\xs => fromHList $
permuteHList p $
toHList xs
134 | toHList : {ts : _} -> (TenSeq LPair (W0 ()) ts).runW0 -> All Wrap0.runW0 ts
135 | toHList {ts=[]} () = []
136 | toHList {ts=[_]} x = [x]
137 | toHList {ts=_::_::_} (x # y) = x :: toHList y
139 | fromHList : All Wrap0.runW0 ts -> (TenSeq LPair (W0 ()) ts).runW0
142 | fromHList (x :: xs@(_ :: _)) = x # fromHList xs
145 | MonSymmetric Linear LEither (W0 Void) where
148 | Bimonoidal Linear LEither LPair (W0 Void) (W0 ()) where
149 | distribl = MkLinear $
\(x # y) => case y of
150 | Left y' => Left (x # y')
151 | Right y' => Right (x # y')
152 | distribl' = MkLinear $
leither (\(x # y) => x # Left y) (\(x # y) => x # Right y)
153 | distribr = MkLinear $
\(x # y) => case x of
154 | Left x' => Left (x' # y)
155 | Right x' => Right (x' # y)
156 | distribr' = MkLinear $
leither (\(x # y) => Left x # y) (\(x # y) => Right x # y)
157 | absorbl = MkLinear $
\(_ # _) impossible
158 | absorbl' = MkLinear $
\_ impossible
159 | absorbr = MkLinear $
\(_ # _) impossible
160 | absorbr' = MkLinear $
\_ impossible
163 | Closed Linear LPair LinearHom (W0 ()) where
164 | curry (MkLinear f) = MkLinear $
\x => MkLinear $
\y => f (x # y)
165 | uncurry (MkLinear f) = MkLinear $
\(x # y) => case f x of MkLinear f' => f' y
172 | namespace SemigroupoidR
174 | Linear : SemigroupoidR
175 | Linear = MkSemigroupoidR Linear
177 | namespace CategoryR
180 | Linear = MkCategoryR Linear
184 | LinearToTyp : FunctorR Linear Typ
185 | LinearToTyp = MkFunctorR id
186 | {impl = MkCatFunctor $
\(MkLinear f) => MkTyp (\x => f x)}
189 | LMaybe : EndofunctorR Linear
190 | LMaybe = MkFunctorR (liftW LMaybe)
192 | namespace BifunctorR
194 | LPair : EndoBifunctorR Linear
195 | LPair = MkBifunctorR LPair
198 | LEither : EndoBifunctorR Linear
199 | LEither = MkBifunctorR LEither
201 | namespace MonoidalR
203 | LinearLPair : MonoidalR
204 | LinearLPair = MkMonoidalR Linear LPair (W0 ())
207 | LinearLEither : MonoidalR
208 | LinearLEither = MkMonoidalR Linear LEither (W0 Void)
212 | LinearLPair : BraidedR
213 | LinearLPair = MkBraidedR Linear LPair (W0 ())
216 | LinearLEither : BraidedR
217 | LinearLEither = MkBraidedR Linear LEither (W0 Void)
219 | namespace SymmetricR
221 | LinearLPair : SymmetricR
222 | LinearLPair = MkSymmetricR Linear LPair (W0 ())
225 | LinearLEither : SymmetricR
226 | LinearLEither = MkSymmetricR Linear LEither (W0 Void)
228 | namespace BimonoidalR
230 | Linear : BimonoidalR
231 | Linear = MkBimonoidalR Linear LEither LPair (W0 Void) (W0 ())
233 | namespace RigCategoryR
235 | Linear : RigCategoryR
236 | Linear = MkRigCategoryR Linear LEither LPair (W0 Void) (W0 ())
238 | namespace SymRigCategoryR
240 | Linear : SymRigCategoryR
241 | Linear = MkSymRigCategoryR Linear LEither LPair (W0 Void) (W0 ())
246 | Linear = MkClosedR Linear LPair LinearHom (W0 ())