2 | import Control.Applicative.Const
3 | import Control.Monad.Identity
4 | import Control.Monad.Reader.Reader
8 | NaturalTransformation : {k : Type} -> (k -> Type) -> (k -> Type) -> Type
9 | NaturalTransformation a b = {x : k} -> a x -> b x
13 | Algebra : {k : Type} -> ((k -> Type) -> k -> Type) -> (k -> Type) -> Type
14 | Algebra f g = NaturalTransformation (f g) g
18 | Coalgebra : {k : Type} -> ((k -> Type) -> k -> Type) -> (k -> Type) -> Type
19 | Coalgebra f g = NaturalTransformation g (f g)
23 | HFunctor : {k1, k2 : Type} -> ((k1 -> Type) -> k2 -> Type) -> Type
24 | HFunctor f = {a, b : k1 -> Type}
25 | -> NaturalTransformation a b -> NaturalTransformation (f a) (f b)
30 | record Nested (t : k -> Type) (f : (k -> Type) -> k -> Type) where
31 | constructor MkNested
32 | hfunctor : HFunctor f
33 | project : Coalgebra f t
38 | hfold : {t, r : k -> Type} -> Nested t f
39 | -> Algebra f r -> NaturalTransformation t r
42 | f : NaturalTransformation t r
43 | f x = a (n.hfunctor f (n.project x))
53 | hbuild : {t : k -> Type} -> Nested t f -> {r : k -> Type}
54 | -> ({x : k -> Type} -> Algebra f x -> NaturalTransformation r x)
55 | -> NaturalTransformation r t
56 | hbuild n f = f n.embed
60 | hunfold : {t, r : k -> Type} -> Nested t f
61 | -> Coalgebra f r -> NaturalTransformation r t
64 | u : NaturalTransformation r t
65 | u x = n.embed (n.hfunctor u (c x))
70 | hdestroy : {t, r : k -> Type} -> Nested t f
71 | -> ({x : k -> Type} -> Coalgebra f x -> NaturalTransformation x r)
72 | -> NaturalTransformation t r
73 | hdestroy n u = u n.project
79 | hhylo : {k : Type} -> {f : (k -> Type) -> k -> Type} -> HFunctor f
80 | -> {i, o : k -> Type} -> Coalgebra f i -> Algebra f o -> NaturalTransformation i o
83 | h : NaturalTransformation i o
86 | HJoin : {k : Type} -> ((k -> Type) -> k -> Type) -> Type
87 | HJoin m = {f : k -> Type} -> NaturalTransformation (m (m f)) (m f)
89 | HDuplicate : {k : Type} -> ((k -> Type) -> k -> Type) -> Type
90 | HDuplicate w = {f : k -> Type} -> NaturalTransformation (w f) (w (w f))
92 | record HMonad (m : (k -> Type) -> k -> Type) where
93 | constructor MkHMonad
94 | hfunctor : HFunctor m
97 | record HComonad (w : (k -> Type) -> k -> Type) where
98 | constructor MkHComonad
99 | hfunctor : HFunctor w
100 | hduplicate : HDuplicate w
102 | HDist : {k : Type} -> (f, g : (k -> Type) -> k -> Type) -> Type
103 | HDist f g = {y : k -> Type} -> NaturalTransformation (f (g y)) (g (f y))
105 | ghhylo : {k : Type} -> {f, m, w : (k -> Type) -> k -> Type}
106 | -> HFunctor f -> HMonad m -> HComonad w
107 | -> HDist m f -> HDist f w
108 | -> {i, o : k -> Type} -> Coalgebra (f . m) i -> Algebra (f . w) o
109 | -> NaturalTransformation i o
110 | ghhylo hmap monad comonad distM distW c a =
111 | a . hmap (hhylo {f} hmap gc ga) . c
113 | gc : Coalgebra f (m i)
114 | gc = hmap monad.hjoin . distM . monad.hfunctor c
115 | ga : Algebra f (w o)
116 | ga = comonad.hfunctor a . distW . hmap comonad.hduplicate
118 | data HFree : (f : (k -> Type) -> k -> Type) -> (a : k -> Type) -> k -> Type where
119 | HFreePure : {x : k} -> a x -> HFree f a x
120 | HFreeWrap : f (HFree f a) x -> HFree f a x
122 | hfunctorHfree : {f : (k -> Type) -> k -> Type}
123 | -> HFunctor f -> HFunctor (HFree f)
124 | hfunctorHfree hmap = freeMap
126 | freeMap : NaturalTransformation a b
127 | -> NaturalTransformation (HFree f a) (HFree f b)
128 | freeMap t = mappedT
130 | mappedT : NaturalTransformation (HFree f a) (HFree f b)
131 | mappedT (HFreePure ax) = HFreePure (t ax)
132 | mappedT (HFreeWrap ffax) = HFreeWrap (hmap mappedT ffax)
134 | hjoinHfree : {g : (k -> Type) -> k -> Type} -> HFunctor g -> HJoin (HFree g)
135 | hjoinHfree hmap = freeJoin
137 | freeJoin : HJoin (HFree g)
138 | freeJoin (HFreePure ffgx) = ffgx
139 | freeJoin (HFreeWrap gfgfgfx) = HFreeWrap (hmap freeJoin gfgfgfx)
141 | hmonadHfree : {f : (k -> Type) -> k -> Type} -> HFunctor f -> HMonad (HFree f)
142 | hmonadHfree hmap = MkHMonad (hfunctorHfree {f} hmap) (hjoinHfree {g=f} hmap)
144 | hdistHfree : {f : (k -> Type) -> k -> Type} -> HFunctor f -> HDist (HFree f) f
145 | hdistHfree hmap = freeDist
147 | freeDist : HDist (HFree f) f
148 | freeDist (HFreePure fyx) = hmap HFreePure fyx
149 | freeDist (HFreeWrap ffffyx) = hmap (HFreeWrap . freeDist) ffffyx
151 | record HCofree (f : (k -> Type) -> k -> Type) (a : k -> Type) (x : k) where
154 | hunwrap : f (HCofree f a) x
156 | hfunctorHcofree : {f : (k -> Type) -> k -> Type}
157 | -> HFunctor f -> HFunctor (HCofree f)
158 | hfunctorHcofree hmap = cofreeMap
160 | cofreeMap : NaturalTransformation a b
161 | -> NaturalTransformation (HCofree f a) (HCofree f b)
162 | cofreeMap t = mappedT
164 | mappedT : NaturalTransformation (HCofree f a) (HCofree f b)
165 | mappedT (ax :< fcfax) = t ax :< hmap mappedT fcfax
167 | hduplicateHcofree : {g : (k -> Type) -> k -> Type}
168 | -> HFunctor g -> HDuplicate (HCofree g)
169 | hduplicateHcofree hmap = cofreeDup
171 | cofreeDup : HDuplicate (HCofree g)
172 | cofreeDup cfg@(ax :< gcfax) = cfg :< hmap cofreeDup gcfax
174 | hcomonadHcofree : {f : (k -> Type) -> k -> Type}
175 | -> HFunctor f -> HComonad (HCofree f)
176 | hcomonadHcofree hmap =
177 | MkHComonad (hfunctorHcofree {f} hmap) (hduplicateHcofree {g=f} hmap)
179 | hdistHcofree : {f : (k -> Type) -> k -> Type}
180 | -> HFunctor f -> HDist f (HCofree f)
181 | hdistHcofree hmap = cofreeDist
183 | cofreeDist : HDist f (HCofree f)
184 | cofreeDist fcfyx = hmap hextract fcfyx :< hmap (cofreeDist . hunwrap) fcfyx
186 | hchrono : {k : Type} -> {f : (k -> Type) -> k -> Type} -> HFunctor f
187 | -> {i, o : k -> Type}
188 | -> Coalgebra (f . HFree f) i -> Algebra (f . HCofree f) o
189 | -> NaturalTransformation i o
193 | (hmonadHfree {f} hmap) (hcomonadHcofree {f} hmap)
194 | (hdistHfree {f} hmap) (hdistHcofree {f} hmap)
198 | Ran : {k : Type} -> (k -> Type) -> (k -> Type) -> Type -> Type
199 | Ran f g a = {y : k} -> (a -> f y) -> g y
201 | mapRan : {a, b : Type} -> (a -> b) -> Ran f g a -> Ran f g b
202 | mapRan f r mk = r (mk . f)
204 | runRan : {a : Type} -> Ran f g a -> (a -> f a) -> g a
211 | gfold : {t, c, r : Type -> Type} -> Nested t f -> Algebra f (Ran c r)
212 | -> {i, o : Type} -> (i -> c o) -> t i -> r o
213 | gfold n a fn tx = hfold n a tx fn
217 | record Lan (f : k -> Type) (g : k -> Type) a where
220 | extract : f target -> a
223 | mapLan : {a, b : Type} -> (a -> b) -> Lan f g a -> Lan f g b
224 | mapLan f l = MkLan (f . l.extract) l.pool
228 | gbuild : {t : Type -> Type} -> Nested t f -> {c, s : Type -> Type}
229 | -> (ghf : {x : Type -> Type}
230 | -> Algebra f x -> NaturalTransformation (Lan c s) x
232 | -> {i, o : Type} -> (c i -> o) -> s i -> t o
233 | gbuild n ghf fn sx = hbuild n ghf (MkLan fn sx)
241 | gunfold : {t, c, s : Type -> Type} -> Nested t f -> Coalgebra f (Lan c s)
242 | -> {i, o : Type} -> (c i -> o) -> s i -> t o
243 | gunfold n ca fn sx = hunfold n ca (MkLan fn sx)
250 | gdestroy : {t, c, r : Type -> Type} -> Nested t f
251 | -> (ghu : {x : Type -> Type} -> Coalgebra f x
252 | -> NaturalTransformation x (Ran c r)
254 | -> {i, o : Type} -> (i -> c o) -> t i -> r o
255 | gdestroy n ghu fn tx = hdestroy n ghu tx fn
259 | Codensity : {k : Type} -> (k -> Type) -> Type -> Type
260 | Codensity f = Ran f f
265 | ghylo : {f : (Type -> Type) -> Type -> Type} -> HFunctor f
266 | -> {s, c, r : Type -> Type}
267 | -> Coalgebra f (Lan c s) -> Algebra f (Ran c r)
268 | -> {i, m, o : Type} -> (m -> c o) -> (c i -> m) -> s i -> r o
269 | ghylo hmap co a ic ec sx = hhylo {f} hmap co a (MkLan ec sx) ic
273 | ffold : {t : Type -> Type} -> Nested t f
274 | -> {a : Type} -> Algebra f (Codensity (Const a)) -> t a -> a
275 | ffold n alg = runConst . gfold n alg {o=Void} MkConst
279 | Density : (k -> Type) -> Type -> Type
280 | Density f = Lan f f
282 | pureDensity : ({0 x : Type} -> x -> f x) -> a -> Density f a
283 | pureDensity puref x = MkLan (const x) (puref MkUnit)
285 | applyDensity : ({0 a, b : Type} -> (a -> b) -> f a -> f b)
286 | -> ({0 x : Type} -> x -> f x)
287 | -> ({0 a, b : Type} -> f (a -> b) -> f a -> f b)
288 | -> Density f (a -> b) -> Density f a -> Density f b
289 | applyDensity mapf puref applyf (MkLan extractf poolf) (MkLan extractx poolx) =
290 | MkLan (\fk => extractf (mapf fst fk) (extractx (mapf snd fk)))
291 | (applyf (applyf (puref MkPair) poolf) poolx)
293 | dupDensity : Density f a -> Density f (Density f a)
294 | dupDensity x = MkLan (const x) (pool x)
299 | fbuild : {t : Type -> Type} -> Nested t f -> {a : Type}
300 | -> (ghf : {x : Type -> Type}
301 | -> Algebra f x -> NaturalTransformation (Density (Const a)) x
304 | fbuild n ghf = gbuild n ghf {i=Void} runConst . MkConst
310 | funfold : {t : Type -> Type} -> Nested t f
311 | -> {a : Type} -> Coalgebra f (Density (Const a)) -> a -> t a
312 | funfold n c = gunfold n c {i=Void} runConst . MkConst
317 | fdestroy : {t : Type -> Type} -> Nested t f -> {a : Type}
318 | -> (ghu : {x : Type -> Type}
320 | -> NaturalTransformation x (Codensity (Const a))
323 | fdestroy n ghu = runConst . gdestroy n ghu {o=Void} MkConst
325 | Recursive : Type -> (Type -> Type) -> Type
326 | Recursive t f = Nested (const t) ((.) f)
328 | mkRecursive : (ffmap : {a, b : Type} -> (a -> b) -> f a -> f b)
329 | -> (project : t -> f t)
330 | -> (embed : f t -> t)
332 | mkRecursive fmap project embed = MkNested hmap project embed
334 | hmap : {a, b : Unit -> Type} -> NaturalTransformation a b
335 | -> NaturalTransformation (f . a) (f . b)
338 | fmap : Recursive t f -> {a, b : Type} -> (a -> b) -> f a -> f b
339 | fmap n fn = n.hfunctor {x = MkUnit} fn
341 | (.fmap) : Recursive t f -> {a, b : Type} -> (a -> b) -> f a -> f b
344 | project : Recursive t f -> t -> f t
345 | project r = r.project {x = MkUnit}
347 | (.project) : Recursive t f -> t -> f t
348 | (.project) = project
350 | embed : Recursive t f -> f t -> t
351 | embed r = r.embed {x = MkUnit}
353 | (.embed) : Recursive t f -> f t -> t
356 | fold : {t : Type} -> Recursive t f -> {a : Type} -> (f a -> a) -> t -> a
357 | fold r alg tx = hfold r alg {x = MkUnit} tx
359 | nmap : {t : Type -> Type} -> Nested t f
360 | -> (ffmap : ({a, b : Type} -> (a -> b) -> t a -> t b)
361 | -> {a, b : Type} -> (a -> b) -> f t a -> f t b)
362 | -> {a, b : Type} -> (a -> b) -> t a -> t b
363 | nmap n ffmap = tmap
365 | tmap : {a, b : Type} -> (a -> b) -> t a -> t b
366 | tmap {a} {b} f = fmap
369 | fmap = n.embed . ffmap tmap f . n.project