quox/examples/list.quox

92 lines
2.7 KiB
Text
Raw Normal View History

2023-04-18 18:42:40 -04:00
load "nat.quox";
2023-07-21 11:57:47 -04:00
namespace vec {
2023-04-18 18:42:40 -04:00
def0 Vec : → ★ → ★ =
2023-03-31 13:31:49 -04:00
λ n A ⇒
2023-05-21 14:33:42 -04:00
caseω n return ★ of {
2023-03-31 13:31:49 -04:00
zero ⇒ {nil};
succ _, 0.Tail ⇒ A × Tail
};
2023-07-21 11:57:47 -04:00
def elim : 0.(A : ★) → 0.(P : (n : ) → Vec n A → ★) →
P 0 'nil →
ω.((x : A) → 0.(n : ) → 0.(xs : Vec n A) →
P n xs → P (succ n) (x, xs)) →
(n : ) → (xs : Vec n A) → P n xs =
λ A P pn pc n ⇒
case n return n' ⇒ (xs' : Vec n' A) → P n' xs' of {
zero ⇒ λ n ⇒
case n return n' ⇒ P 0 n' of { 'nil ⇒ pn };
succ n, ih ⇒ λ c ⇒
case c return c' ⇒ P (succ n) c' of {
(first, rest) ⇒ pc first n rest (ih rest)
}
};
2023-11-03 12:42:44 -04:00
#[compile-scheme "(lambda% (n xs) xs)"]
2023-07-22 15:26:20 -04:00
def up : 0.(A : ★) → (n : ) → Vec n A → Vec¹ n A =
λ A n ⇒
case n return n' ⇒ Vec n' A → Vec¹ n' A of {
zero ⇒ λ xs ⇒
case xs return Vec¹ 0 A of { 'nil ⇒ 'nil };
succ n', f' ⇒ λ xs ⇒
case xs return Vec¹ (succ n') A of {
(first, rest) ⇒ (first, f' rest)
}
}
2023-07-21 11:57:47 -04:00
}
def0 Vec = vec.Vec;
namespace list {
def0 List : ★ → ★ =
2023-03-31 13:31:49 -04:00
λ A ⇒ (len : ) × Vec len A;
2023-07-21 11:57:47 -04:00
def Nil : 0.(A : ★) → List A =
2023-03-31 13:31:49 -04:00
λ A ⇒ (0, 'nil);
2023-07-21 11:57:47 -04:00
def Cons : 0.(A : ★) → A → List A → List A =
λ A x xs ⇒ case xs return List A of { (len, elems) ⇒ (succ len, x, elems) };
2023-04-17 15:44:16 -04:00
2023-07-21 11:57:47 -04:00
def elim : 0.(A : ★) → 0.(P : List A → ★) →
P (Nil A) →
ω.((x : A) → 0.(xs : List A) → P xs → P (Cons A x xs)) →
(xs : List A) → P xs =
λ A P pn pc xs ⇒
case xs return xs' ⇒ P xs' of { (len, elems) ⇒
vec.elim A (λ n xs ⇒ P (n, xs))
pn (λ x n xs ih ⇒ pc x (n, xs) ih)
len elems
};
2023-07-22 15:26:20 -04:00
-- [fixme] List A <: List¹ A should be automatic, imo
2023-11-03 12:42:44 -04:00
#[compile-scheme "(lambda (xs) xs)"]
2023-07-22 15:26:20 -04:00
def up : 0.(A : ★) → List A → List¹ A =
λ A xs ⇒
case xs return List¹ A of { (len, elems) ⇒
case nat.dup! len return List¹ A of { [p] ⇒
caseω p return List¹ A of { (lenω, eq0) ⇒
case eq0 return List¹ A of { [eq] ⇒
(lenω, vec.up A lenω (coe (𝑖 ⇒ Vec (eq @𝑖) A) @1 @0 elems))
}
}
}
};
def foldr : 0.(A B : ★) → B → ω.(A → B → B) → List A → B =
2023-07-21 11:57:47 -04:00
λ A B z f xs ⇒ elim A (λ _ ⇒ B) z (λ x _ y ⇒ f x y) xs;
2023-03-31 13:31:49 -04:00
2023-07-21 11:57:47 -04:00
def map : 0.(A B : ★) → ω.(A → B) → List A → List B =
λ A B f ⇒ foldr A (List B) (Nil B) (λ x ys ⇒ Cons B (f x) ys);
2023-03-31 13:31:49 -04:00
2023-07-22 15:26:20 -04:00
def0 All : (A : ★) → (P : A → ★) → List A → ★ =
λ A P xs ⇒ foldr¹ A ★ True (λ x ps ⇒ P x × ps) (up A xs);
2023-04-18 18:42:40 -04:00
}
2023-07-21 11:57:47 -04:00
def0 List = list.List;