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:
File diff suppressed because one or more lines are too long
+33
-1
@@ -161,4 +161,36 @@
|
||||
(case (pat-ctor Cons h t)
|
||||
(if (app p h)
|
||||
(term-ctor List Cons h (app filter p t))
|
||||
(app filter p t)))))))
|
||||
(app filter p t))))))
|
||||
|
||||
(fn take
|
||||
(doc "First n elements of xs (or all of xs if it has fewer than n).")
|
||||
(type
|
||||
(forall (vars a)
|
||||
(fn-type
|
||||
(params (con Int) (con List a))
|
||||
(ret (con List a)))))
|
||||
(params n xs)
|
||||
(body
|
||||
(if (app <= n 0)
|
||||
(term-ctor List Nil)
|
||||
(match xs
|
||||
(case (pat-ctor Nil) (term-ctor List Nil))
|
||||
(case (pat-ctor Cons h t)
|
||||
(term-ctor List Cons h (app take (app - n 1) t)))))))
|
||||
|
||||
(fn drop
|
||||
(doc "All elements of xs after the first n (or Nil if xs has fewer than n elements).")
|
||||
(type
|
||||
(forall (vars a)
|
||||
(fn-type
|
||||
(params (con Int) (con List a))
|
||||
(ret (con List a)))))
|
||||
(params n xs)
|
||||
(body
|
||||
(if (app <= n 0)
|
||||
xs
|
||||
(match xs
|
||||
(case (pat-ctor Nil) (term-ctor List Nil))
|
||||
(case (pat-ctor Cons _ t)
|
||||
(app drop (app - n 1) t)))))))
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{"defs":[{"doc":"The canonical [1, 2, 3, 4, 5] used across all checks.","kind":"const","name":"xs","type":{"args":[{"k":"con","name":"Int"}],"k":"con","name":"std_list.List"},"value":{"args":[{"lit":{"kind":"int","value":1},"t":"lit"},{"args":[{"lit":{"kind":"int","value":2},"t":"lit"},{"args":[{"lit":{"kind":"int","value":3},"t":"lit"},{"args":[{"lit":{"kind":"int","value":4},"t":"lit"},{"args":[{"lit":{"kind":"int","value":5},"t":"lit"},{"args":[],"ctor":"Nil","t":"ctor","type":"std_list.List"}],"ctor":"Cons","t":"ctor","type":"std_list.List"}],"ctor":"Cons","t":"ctor","type":"std_list.List"}],"ctor":"Cons","t":"ctor","type":"std_list.List"}],"ctor":"Cons","t":"ctor","type":"std_list.List"}],"ctor":"Cons","t":"ctor","type":"std_list.List"}},{"body":{"lhs":{"args":[{"args":[{"args":[{"lit":{"kind":"int","value":0},"t":"lit"},{"name":"xs","t":"var"}],"fn":{"name":"std_list.take","t":"var"},"t":"app"}],"fn":{"name":"std_list.length","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"lhs":{"args":[{"args":[{"args":[{"lit":{"kind":"int","value":3},"t":"lit"},{"name":"xs","t":"var"}],"fn":{"name":"std_list.take","t":"var"},"t":"app"}],"fn":{"name":"std_list.length","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"lhs":{"args":[{"args":[{"args":[{"lit":{"kind":"int","value":100},"t":"lit"},{"name":"xs","t":"var"}],"fn":{"name":"std_list.take","t":"var"},"t":"app"}],"fn":{"name":"std_list.length","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"lhs":{"args":[{"args":[{"args":[{"lit":{"kind":"int","value":0},"t":"lit"},{"name":"xs","t":"var"}],"fn":{"name":"std_list.drop","t":"var"},"t":"app"}],"fn":{"name":"std_list.length","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"lhs":{"args":[{"args":[{"args":[{"lit":{"kind":"int","value":2},"t":"lit"},{"name":"xs","t":"var"}],"fn":{"name":"std_list.drop","t":"var"},"t":"app"}],"fn":{"name":"std_list.length","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"args":[{"args":[{"args":[{"lit":{"kind":"int","value":100},"t":"lit"},{"name":"xs","t":"var"}],"fn":{"name":"std_list.drop","t":"var"},"t":"app"}],"fn":{"name":"std_list.length","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"t":"seq"},"t":"seq"},"t":"seq"},"t":"seq"},"t":"seq"},"doc":"Expected output (one per line): 0, 3, 5, 5, 3, 0.","kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[{"module":"std_list"}],"name":"std_list_more_demo","schema":"ailang/v0"}
|
||||
@@ -0,0 +1,32 @@
|
||||
; Iter 15h — demo for the new std_list combinators `take` and `drop`.
|
||||
; Uses a top-level `(const xs)` for the canonical [1, 2, 3, 4, 5] —
|
||||
; pure ctor expression, so a const is fine (same idiom as
|
||||
; std_list_demo). Six checks pin both n=0, 0<n<length, and n>length
|
||||
; boundaries on each combinator.
|
||||
|
||||
(module std_list_more_demo
|
||||
|
||||
(import std_list)
|
||||
|
||||
(const xs
|
||||
(doc "The canonical [1, 2, 3, 4, 5] used across all checks.")
|
||||
(type (con std_list.List (con Int)))
|
||||
(body
|
||||
(term-ctor std_list.List Cons 1
|
||||
(term-ctor std_list.List Cons 2
|
||||
(term-ctor std_list.List Cons 3
|
||||
(term-ctor std_list.List Cons 4
|
||||
(term-ctor std_list.List Cons 5
|
||||
(term-ctor std_list.List Nil))))))))
|
||||
|
||||
(fn main
|
||||
(doc "Expected output (one per line): 0, 3, 5, 5, 3, 0.")
|
||||
(type (fn-type (params) (ret (con Unit)) (effects IO)))
|
||||
(params)
|
||||
(body
|
||||
(seq (do io/print_int (app std_list.length (app std_list.take 0 xs)))
|
||||
(seq (do io/print_int (app std_list.length (app std_list.take 3 xs)))
|
||||
(seq (do io/print_int (app std_list.length (app std_list.take 100 xs)))
|
||||
(seq (do io/print_int (app std_list.length (app std_list.drop 0 xs)))
|
||||
(seq (do io/print_int (app std_list.length (app std_list.drop 2 xs)))
|
||||
(do io/print_int (app std_list.length (app std_list.drop 100 xs)))))))))))
|
||||
Reference in New Issue
Block a user