Iter 15h — std_list extension: take, drop
Adds the two canonical prefix-slicing combinators to std_list.
First fns in std_list to combine `if` + Int arithmetic + recursive
ADT pattern in one body.
take : forall a. (Int, List<a>) -> List<a>
— first n elements (or all of xs if shorter than n).
drop : forall a. (Int, List<a>) -> List<a>
— list with first n elements removed (Nil if n >= length).
Both use `(if (<= n 0) ...)` as the base-case guard since
literal sub-patterns inside Ctor patterns aren't yet supported
(queued as 16c — would let take/drop collapse the if into the
match).
examples/std_list_more_demo: builds [1, 2, 3, 4, 5] once and
exercises take/drop at n=0, n=mid, n=overflow on each. Expected
output 0, 3, 5, 5, 3, 0 (one per line).
Tests: 95/95 (e2e went from 35 to 36). std_list grew from 10 to
12 combinators; total stdlib 5 modules / 29 combinators. No new
compiler bug surfaced.
Pre-existing std_list defs are byte-identical (verified via diff
on .ailx and round-trip on .ail.json), so the five downstream
importers (std_list_demo, std_list_stress, std_either_list,
std_either_list_demo, list_map_poly) need no regeneration.
This commit is contained in:
@@ -417,6 +417,21 @@ fn std_either_list_demo() {
|
||||
assert_eq!(lines, vec!["2", "3", "2", "3"]);
|
||||
}
|
||||
|
||||
/// Iter 15h: `std_list.take` and `std_list.drop` end-to-end. Both are
|
||||
/// index-driven recursive ADT-pattern fns — the first `std_list`
|
||||
/// combinators that pair `if (<= n 0)` Int-arithmetic guards with a
|
||||
/// recursive Cons/Nil match. Property protected: the `if` base-case
|
||||
/// guard wraps a `match` whose recursive arm bodies use `(- n 1)` and
|
||||
/// re-enter through `app` — a shape no other `std_list` fn has so
|
||||
/// far. Six checks pin all three boundary regimes (n=0, 0<n<length,
|
||||
/// n>length) on each combinator. Expected stdout: 0, 3, 5, 5, 3, 0.
|
||||
#[test]
|
||||
fn std_list_more_demo() {
|
||||
let stdout = build_and_run("std_list_more_demo.ail.json");
|
||||
let lines: Vec<&str> = stdout.lines().collect();
|
||||
assert_eq!(lines, vec!["0", "3", "5", "5", "3", "0"]);
|
||||
}
|
||||
|
||||
/// Guards `ail diff`: a modified body changes the hash of `sum`, while
|
||||
/// `main` stays unchanged. Expects exit code 1, `changed` contains exactly
|
||||
/// `sum`, `unchanged` contains `main`, `added`/`removed` empty.
|
||||
|
||||
Reference in New Issue
Block a user