5 | module Data.Description.Indexed
10 | data IDesc : (p : Type -> Type) -> (i : Type) -> Type where
14 | (*) : (d1, d2 : IDesc p i) -> IDesc p i
15 | (+) : (d1, d2 : IDesc p i) -> IDesc p i
16 | Sig : (s : Type) -> p s -> (s -> IDesc p i) -> IDesc p i
19 | Elem : IDesc p i -> (i -> Type) -> Type
23 | Elem (d1 * d2) x = (Elem d1 x, Elem d2 x)
24 | Elem (d1 + d2) x = Either (Elem d1 x) (Elem d2 x)
25 | Elem (Sig s prop d) x = (v : s ** Elem (d v) x)
28 | data Fix : (i -> IDesc p i) -> i -> Type where
29 | MkFix : assert_total (Elem (d i) (Fix d)) -> Fix d i
33 | VecD : Type -> Nat -> IDesc (const ()) Nat
35 | VecD a (S n) = Sig a () (const (Id n))
38 | map : (d : IDesc p i) -> ((v : i) -> x v -> y v) -> Elem d x -> Elem d y
41 | map (Id i) f v = f i v
42 | map (d1 * d2) f (v, w) = (map d1 f v, map d2 f w)
43 | map (d1 + d2) f (Left v) = Left (map d1 f v)
44 | map (d1 + d2) f (Right v) = Right (map d2 f v)
45 | map (Sig s _ d) f (
x ** v)
= (
x ** map (d x) f v)
48 | ifold : {d : i -> IDesc p i} ->
49 | ((v : i) -> Elem (d v) x -> x v) ->
50 | {v : i} -> Fix d v -> x v
51 | ifold alg (MkFix t) = alg v (assert_total $
Indexed.map (d v) (\ _ => ifold alg) t)