14 | data Repr : Type where
17 | RTwo : Repr -> Repr -> Repr
23 | data Children : Repr -> Type -> Type where
24 | Zero : Children RZero a
25 | One : a -> Children ROne a
26 | Two : Children l a -> Children r a -> Children (RTwo l r) a
29 | Functor (Children repr) where
31 | map f (One x) = One (f x)
32 | map f (Two x y) = Two (map f x) (map f y)
35 | Foldable (Children repr) where
37 | foldr f z (One x) = f x z
38 | foldr f z (Two x y) = foldr f (foldr f z y) x
41 | foldl f z (One x) = f z x
42 | foldl f z (Two x y) = foldl f (foldl f z x) y
47 | foldlM f z Zero = pure z
48 | foldlM f z (One x) = f z x
49 | foldlM f z (Two x y) = foldlM f z x >>= (\z => foldlM f z y)
51 | toList cs = toListOnto cs []
53 | toListOnto : forall repr. Children repr ty -> List ty -> List ty
54 | toListOnto Zero acc = acc
55 | toListOnto (One x) acc = x :: acc
56 | toListOnto (Two x y) acc = toListOnto x $
toListOnto y acc
58 | foldMap f Zero = neutral
59 | foldMap f (One x) = f x
60 | foldMap f (Two x y) = foldMap f x <+> foldMap f y
63 | Traversable (Children repr) where
64 | traverse f Zero = pure Zero
65 | traverse f (One x) = One <$> f x
66 | traverse f (Two x y) = Two <$> traverse f x <*> traverse f y
69 | record Plate (from : Type) (to : Type) where
72 | cs : Children repr to
73 | gen : Children repr to -> from
76 | interface Uniplate ty where
79 | uniplate : (x : ty) -> Plate ty ty
81 | descend : (ty -> ty) -> ty -> ty
83 | let MkPlate cs gen = uniplate x
86 | descendM : Applicative m => (ty -> m ty) -> ty -> m ty
88 | let MkPlate cs gen = uniplate x
89 | in gen <$> traverse f cs
92 | interface Uniplate to => Biplate from to where
93 | biplate : (x : from) -> Plate from to
95 | bidescend : (to -> to) -> from -> from
97 | let MkPlate cs gen = biplate x
100 | bidescendM : Applicative m => (to -> m to) -> from -> m from
102 | let MkPlate cs gen = biplate x
103 | in gen <$> traverse f cs
105 | compose : Biplate t a => Children r t -> Plate (Children r t) a
106 | compose Zero = MkPlate Zero (\Zero => Zero)
108 | let MkPlate cs gen = biplate x
109 | in MkPlate cs (\cs => One (gen cs))
110 | compose (Two x y) =
111 | let MkPlate xs genx = compose x
112 | MkPlate ys geny = compose y
113 | in MkPlate (Two xs ys) (\(Two xs ys) => Two (genx xs) (geny ys))
116 | [Compose] Biplate outer inner => Biplate inner to => Biplate outer to where
118 | let MkPlate os geno = biplate {to = inner} x
119 | MkPlate is geni = compose os
120 | in MkPlate is (\is => geno (geni is))
123 | let MkPlate cs gen = biplate @{Compose {outer, inner, to}} x
126 | let MkPlate cs gen = biplate @{Compose {outer, inner, to}} x
127 | in gen <$> traverse f cs
130 | children : Uniplate ty => ty -> List ty
131 | children x = toList $
cs $
uniplate x
135 | plate : from -> Plate from to
136 | plate x = MkPlate { cs = Zero, gen = \Zero => x}
140 | (|*) : Plate (to -> from) to -> to -> Plate from to
141 | MkPlate cs gen |* x = MkPlate (Two cs (One x)) (\(Two cs (One x)) => gen cs x)
146 | public export %tcinline
149 | Plate (item -> from) to ->
152 | MkPlate ls lgen |+ x =
153 | let MkPlate rs rgen = biplate x
154 | in MkPlate (Two ls rs) (\(Two ls rs) => lgen ls (rgen rs))
158 | public export %tcinline
161 | Biplate (f inner) inner =>
162 | Biplate inner to =>
163 | Plate (f inner -> from) to ->
166 | p ||+ x = (|+) @{Compose {outer = f inner, inner, to}} p x
170 | (|-) : Plate (item -> from) to -> item -> Plate from to
171 | MkPlate cs gen |- x = MkPlate cs (\cs => gen cs x)
176 | plateStar : (to -> from) -> to -> Plate from to
177 | plateStar f x = MkPlate (One x) (\(One x) => f x)
182 | public export %tcinline
183 | platePlus : Biplate item to => (item -> from) -> (x : item) -> Plate from to
185 | let MkPlate cs gen = biplate x
186 | in MkPlate cs (\cs => f (gen cs))
191 | plateVia : Biplate s to => (f : s -> t) -> (g : t -> s) -> t -> Plate t to
193 | let MkPlate cs gen = biplate $
g x
194 | in MkPlate cs (\cs => f (gen cs))
199 | universe : Uniplate ty => ty -> List ty
200 | universe x = x :: assert_total (foldMap universe (uniplate x).cs)
204 | transform : Uniplate ty => (ty -> ty) -> ty -> ty
205 | transform f = f . assert_total (descend (transform f))
209 | transformM : Uniplate ty => Monad m => (ty -> m ty) -> ty -> m ty
210 | transformM f = assert_total (descendM (transformM f)) >=> f
214 | biuniverse : Biplate from to => from -> List to
215 | biuniverse x = foldMap universe (biplate x).cs
219 | bitransform : Biplate from to => (to -> to) -> from -> from
220 | bitransform f = bidescend (transform f)
224 | bitransformM : Biplate from to => Monad m => (to -> m to) -> from -> m from
225 | bitransformM f = bidescendM (transformM f)
234 | public export covering %inline
235 | fixpoint : Uniplate ty => (ty -> Maybe ty) -> ty -> ty
236 | fixpoint f = transform fix
239 | fix x = maybe x (fixpoint f) (f x)
244 | fixAdd : (a -> Maybe b) -> (a -> Maybe b) -> (a -> Maybe b)
245 | fixAdd f g x = f x <|> g x
250 | para : Uniplate ty => (ty -> List r -> r) -> ty -> r
251 | para f x = f x $
assert_total $
map (para f) $
children x
256 | [Id] Uniplate a where
257 | uniplate x = plateStar id x
260 | [FromUni] Uniplate a => Biplate a a where
264 | Uniplate (List a) where
265 | uniplate [] = plate []
266 | uniplate (x :: xs) = plateStar (x ::) xs
269 | Biplate (List a) a using Id where
270 | biplate [] = plate []
271 | biplate (x :: xs) = assert_total $
plateStar (::) x |+ xs
274 | Biplate (Maybe a) a using Id where
275 | biplate Nothing = plate Nothing
276 | biplate (Just x) = plateStar Just x
279 | Uniplate (SnocList a) where
280 | uniplate [<] = plate [<]
281 | uniplate (xs :< x) = plateStar (:< x) xs
284 | Biplate (SnocList a) a using Id where
285 | biplate [<] = plate [<]
286 | biplate (xs :< x) = assert_total $
platePlus (:<) xs |* x
289 | Biplate (Vect len a) a using Id where
290 | biplate [] = plate []
291 | biplate (x :: xs) = plateStar (::) x |+ xs
294 | Biplate (List1 a) a using Id where
295 | biplate (x ::: xs) = plateStar (:::) x |+ xs
298 | Biplate String Char using Id where
299 | biplate str = plateVia pack unpack str