2 | import Control.Applicative.Const
3 | import Control.Monad.Identity
4 | import Control.Monad.Reader.Reader
10 | NaturalTransformation : {k : Type} -> (k -> Type) -> (k -> Type) -> Type
11 | NaturalTransformation a b = {x : k} -> a x -> b x
15 | Algebra : {k : Type} -> ((k -> Type) -> k -> Type) -> (k -> Type) -> Type
16 | Algebra f g = NaturalTransformation (f g) g
20 | Coalgebra : {k : Type} -> ((k -> Type) -> k -> Type) -> (k -> Type) -> Type
21 | Coalgebra f g = NaturalTransformation g (f g)
25 | HFunctor : {k1, k2 : Type} -> ((k1 -> Type) -> k2 -> Type) -> Type
26 | HFunctor f = {a, b : k1 -> Type}
27 | -> NaturalTransformation a b -> NaturalTransformation (f a) (f b)
32 | record Nested (t : k -> Type) (f : (k -> Type) -> k -> Type) where
33 | constructor MkNested
34 | hfunctor : HFunctor f
35 | project : Coalgebra f t
46 | hfold : {t, r : k -> Type} -> Nested t f
47 | -> Algebra f r -> NaturalTransformation t r
50 | f : NaturalTransformation t r
51 | f x = a (n.hfunctor f (n.project x))
61 | hbuild : {t : k -> Type} -> Nested t f -> {r : k -> Type}
62 | -> ({x : k -> Type} -> Algebra f x -> NaturalTransformation r x)
63 | -> NaturalTransformation r t
64 | hbuild n f = f n.embed
73 | hunfold : {t, r : k -> Type} -> Nested t f
74 | -> Coalgebra f r -> NaturalTransformation r t
77 | u : NaturalTransformation r t
78 | u x = n.embed (n.hfunctor u (c x))
83 | hdestroy : {t, r : k -> Type} -> Nested t f
84 | -> ({x : k -> Type} -> Coalgebra f x -> NaturalTransformation x r)
85 | -> NaturalTransformation t r
86 | hdestroy n u = u n.project
97 | hhylo : {k : Type} -> {f : (k -> Type) -> k -> Type} -> HFunctor f
98 | -> {i, o : k -> Type} -> Coalgebra f i -> Algebra f o -> NaturalTransformation i o
101 | h : NaturalTransformation i o
104 | HJoin : {k : Type} -> ((k -> Type) -> k -> Type) -> Type
105 | HJoin m = {f : k -> Type} -> NaturalTransformation (m (m f)) (m f)
107 | HDuplicate : {k : Type} -> ((k -> Type) -> k -> Type) -> Type
108 | HDuplicate w = {f : k -> Type} -> NaturalTransformation (w f) (w (w f))
110 | record HMonad (m : (k -> Type) -> k -> Type) where
111 | constructor MkHMonad
112 | hfunctor : HFunctor m
115 | record HComonad (w : (k -> Type) -> k -> Type) where
116 | constructor MkHComonad
117 | hfunctor : HFunctor w
118 | hduplicate : HDuplicate w
120 | HDist : {k : Type} -> (f, g : (k -> Type) -> k -> Type) -> Type
121 | HDist f g = {y : k -> Type} -> NaturalTransformation (f (g y)) (g (f y))
125 | ghhylo : {k : Type} -> {f, m, w : (k -> Type) -> k -> Type}
126 | -> HFunctor f -> HMonad m -> HComonad w
127 | -> HDist m f -> HDist f w
128 | -> {i, o : k -> Type} -> Coalgebra (f . m) i -> Algebra (f . w) o
129 | -> NaturalTransformation i o
130 | ghhylo hmap monad comonad distM distW c a =
131 | a . hmap (hhylo {f} hmap gc ga) . c
133 | gc : Coalgebra f (m i)
134 | gc = hmap monad.hjoin . distM . monad.hfunctor c
135 | ga : Algebra f (w o)
136 | ga = comonad.hfunctor a . distW . hmap comonad.hduplicate
138 | data HFree : (f : (k -> Type) -> k -> Type) -> (a : k -> Type) -> k -> Type where
139 | HFreePure : {x : k} -> a x -> HFree f a x
140 | HFreeWrap : {y : k -> Type} -> f y x -> (NaturalTransformation y (HFree f a)) -> HFree f a x
142 | hfreeWrap : {f : (k -> Type) -> k -> Type} -> {a : k -> Type} -> NaturalTransformation (f (HFree f a)) (HFree f a)
143 | hfreeWrap fffa = HFreeWrap fffa id
145 | hfunctorHfree : {f : (k -> Type) -> k -> Type}
146 | -> HFunctor f -> HFunctor (HFree f)
147 | hfunctorHfree hmap = freeMap
149 | freeMap : NaturalTransformation a b
150 | -> NaturalTransformation (HFree f a) (HFree f b)
151 | freeMap t = mappedT
153 | mappedT : NaturalTransformation (HFree f a) (HFree f b)
154 | mappedT (HFreePure ax) = HFreePure (t ax)
155 | mappedT (HFreeWrap fyx ntyf) = HFreeWrap fyx (mappedT . ntyf)
157 | hjoinHfree : {g : (k -> Type) -> k -> Type} -> HFunctor g -> HJoin (HFree g)
158 | hjoinHfree hmap = freeJoin
160 | freeJoin : HJoin (HFree g)
161 | freeJoin (HFreePure ffgx) = ffgx
162 | freeJoin (HFreeWrap fyx ntyfgfgx) = HFreeWrap fyx (freeJoin . ntyfgfgx)
164 | hmonadHfree : {f : (k -> Type) -> k -> Type} -> HFunctor f -> HMonad (HFree f)
165 | hmonadHfree hmap = MkHMonad (hfunctorHfree {f} hmap) (hjoinHfree {g=f} hmap)
167 | hdistHfree : {f : (k -> Type) -> k -> Type} -> HFunctor f -> HDist (HFree f) f
168 | hdistHfree hmap = freeDist
170 | freeDist : HDist (HFree f) f
171 | freeDist (HFreePure fyx) = hmap HFreePure fyx
172 | freeDist (HFreeWrap fyx ntyff) = hmap (hfreeWrap . freeDist . ntyff) fyx
174 | record HCofree (f : (k -> Type) -> k -> Type) (a : k -> Type) (z : k) where
175 | constructor MkHCofree
179 | hstep : NaturalTransformation y (HCofree f a)
181 | hunwrap : {f : (k -> Type) -> k -> Type} -> HFunctor f -> {a : k -> Type} -> NaturalTransformation (HCofree f a) (f (HCofree f a))
182 | hunwrap hmap (MkHCofree _ seed step) = hmap step seed
184 | hfunctorHcofree : {f : (k -> Type) -> k -> Type}
185 | -> HFunctor f -> HFunctor (HCofree f)
186 | hfunctorHcofree hmap = cofreeMap
188 | cofreeMap : NaturalTransformation a b
189 | -> NaturalTransformation (HCofree f a) (HCofree f b)
190 | cofreeMap t = mappedT
192 | mappedT : NaturalTransformation (HCofree f a) (HCofree f b)
193 | mappedT (MkHCofree ax fyx ntyc) = MkHCofree (t ax) fyx (mappedT . ntyc)
195 | hduplicateHcofree : {g : (k -> Type) -> k -> Type}
196 | -> HFunctor g -> HDuplicate (HCofree g)
197 | hduplicateHcofree hmap = cofreeDup
199 | cofreeDup : HDuplicate (HCofree g)
200 | cofreeDup cfg@(MkHCofree az fyz ntyhfa) =
201 | MkHCofree cfg fyz (cofreeDup . ntyhfa)
203 | hcomonadHcofree : {f : (k -> Type) -> k -> Type}
204 | -> HFunctor f -> HComonad (HCofree f)
205 | hcomonadHcofree hmap =
206 | MkHComonad (hfunctorHcofree {f} hmap) (hduplicateHcofree {g=f} hmap)
209 | hdistHcofree : {f : (k -> Type) -> k -> Type}
210 | -> HFunctor f -> HDist f (HCofree f)
211 | hdistHcofree hmap = cofreeDist
213 | cofreeDist : HDist f (HCofree f)
215 | MkHCofree (hmap hextract fcfyx) fcfyx (cofreeDist . hunwrap {f} hmap)
218 | hchrono : {k : Type} -> {f : (k -> Type) -> k -> Type} -> HFunctor f
219 | -> {i, o : k -> Type}
220 | -> Coalgebra (f . HFree f) i -> Algebra (f . HCofree f) o
221 | -> NaturalTransformation i o
225 | (hmonadHfree {f} hmap) (hcomonadHcofree {f} hmap)
226 | (hdistHfree {f} hmap) (hdistHcofree {f} hmap)
230 | Ran : {k : Type} -> (k -> Type) -> (k -> Type) -> Type -> Type
231 | Ran f g a = {y : k} -> (a -> f y) -> g y
233 | mapRan : {a, b : Type} -> (a -> b) -> Ran f g a -> Ran f g b
234 | mapRan f r mk = r (mk . f)
236 | runRan : {a : Type} -> Ran f g a -> (a -> f a) -> g a
244 | gfold : {t, c, r : Type -> Type} -> Nested t f -> Algebra f (Ran c r)
245 | -> {i, o : Type} -> (i -> c o) -> t i -> r o
246 | gfold n a fn tx = hfold n a tx fn
250 | record Lan (f : k -> Type) (g : k -> Type) a where
253 | extract : f target -> a
256 | mapLan : {a, b : Type} -> (a -> b) -> Lan f g a -> Lan f g b
257 | mapLan f l = MkLan (f . l.extract) l.pool
261 | gbuild : {t : Type -> Type} -> Nested t f -> {c, s : Type -> Type}
262 | -> (ghf : {x : Type -> Type}
263 | -> Algebra f x -> NaturalTransformation (Lan c s) x
265 | -> {i, o : Type} -> (c i -> o) -> s i -> t o
266 | gbuild n ghf fn sx = hbuild n ghf (MkLan fn sx)
275 | gunfold : {t, c, s : Type -> Type} -> Nested t f -> Coalgebra f (Lan c s)
276 | -> {i, o : Type} -> (c i -> o) -> s i -> t o
277 | gunfold n ca fn sx = hunfold n ca (MkLan fn sx)
284 | gdestroy : {t, c, r : Type -> Type} -> Nested t f
285 | -> (ghu : {x : Type -> Type} -> Coalgebra f x
286 | -> NaturalTransformation x (Ran c r)
288 | -> {i, o : Type} -> (i -> c o) -> t i -> r o
289 | gdestroy n ghu fn tx = hdestroy n ghu tx fn
293 | Codensity : {k : Type} -> (k -> Type) -> Type -> Type
294 | Codensity f = Ran f f
300 | ghylo : {f : (Type -> Type) -> Type -> Type} -> HFunctor f
301 | -> {s, c, r : Type -> Type}
302 | -> Coalgebra f (Lan c s) -> Algebra f (Ran c r)
303 | -> {i, m, o : Type} -> (m -> c o) -> (c i -> m) -> s i -> r o
304 | ghylo hmap co a ic ec sx = hhylo {f} hmap co a (MkLan ec sx) ic
309 | ffold : {t : Type -> Type} -> Nested t f
310 | -> {a : Type} -> Algebra f (Codensity (Const a)) -> t a -> a
311 | ffold n alg = runConst . gfold n alg {o=Void} MkConst
315 | Density : (k -> Type) -> Type -> Type
316 | Density f = Lan f f
318 | pureDensity : ({0 x : Type} -> x -> f x) -> a -> Density f a
319 | pureDensity puref x = MkLan (const x) (puref MkUnit)
321 | applyDensity : ({0 a, b : Type} -> (a -> b) -> f a -> f b)
322 | -> ({0 x : Type} -> x -> f x)
323 | -> ({0 a, b : Type} -> f (a -> b) -> f a -> f b)
324 | -> Density f (a -> b) -> Density f a -> Density f b
325 | applyDensity mapf puref applyf (MkLan extractf poolf) (MkLan extractx poolx) =
326 | MkLan (\fk => extractf (mapf fst fk) (extractx (mapf snd fk)))
327 | (applyf (applyf (puref MkPair) poolf) poolx)
329 | dupDensity : Density f a -> Density f (Density f a)
330 | dupDensity x = MkLan (const x) (pool x)
335 | fbuild : {t : Type -> Type} -> Nested t f -> {a : Type}
336 | -> (ghf : {x : Type -> Type}
337 | -> Algebra f x -> NaturalTransformation (Density (Const a)) x
340 | fbuild n ghf = gbuild n ghf {i=Void} runConst . MkConst
347 | funfold : {t : Type -> Type} -> Nested t f
348 | -> {a : Type} -> Coalgebra f (Density (Const a)) -> a -> t a
349 | funfold n c = gunfold n c {i=Void} runConst . MkConst
354 | fdestroy : {t : Type -> Type} -> Nested t f -> {a : Type}
355 | -> (ghu : {x : Type -> Type}
357 | -> NaturalTransformation x (Codensity (Const a))
360 | fdestroy n ghu = runConst . gdestroy n ghu {o=Void} MkConst
362 | Recursive : Type -> (Type -> Type) -> Type
363 | Recursive t f = Nested (const t) ((.) f)
365 | mkRecursive : (ffmap : {a, b : Type} -> (a -> b) -> f a -> f b)
366 | -> (project : t -> f t)
367 | -> (embed : f t -> t)
369 | mkRecursive fmap project embed = MkNested hmap project embed
371 | hmap : {a, b : Unit -> Type} -> NaturalTransformation a b
372 | -> NaturalTransformation (f . a) (f . b)
375 | fmap : Recursive t f -> {a, b : Type} -> (a -> b) -> f a -> f b
376 | fmap n fn = n.hfunctor {x = MkUnit} fn
378 | (.fmap) : Recursive t f -> {a, b : Type} -> (a -> b) -> f a -> f b
381 | project : Recursive t f -> t -> f t
382 | project r = r.project {x = MkUnit}
384 | (.project) : Recursive t f -> t -> f t
385 | (.project) = project
387 | embed : Recursive t f -> f t -> t
388 | embed r = r.embed {x = MkUnit}
390 | (.embed) : Recursive t f -> f t -> t
394 | fold : {t : Type} -> Recursive t f -> {a : Type} -> (f a -> a) -> t -> a
395 | fold r alg tx = hfold r alg {x = MkUnit} tx
398 | nmap : {t : Type -> Type} -> Nested t f
399 | -> (ffmap : ({a, b : Type} -> (a -> b) -> t a -> t b)
400 | -> {a, b : Type} -> (a -> b) -> f t a -> f t b)
401 | -> {a, b : Type} -> (a -> b) -> t a -> t b
402 | nmap n ffmap = tmap
404 | tmap : {a, b : Type} -> (a -> b) -> t a -> t b
405 | tmap {a} {b} f = fmap
408 | fmap = n.embed . ffmap tmap f . n.project