Files
AILang/examples/std_either_list.ail.json
T
Brummel e1587ebdae Iter 15g — std_either_list: first 3-way cross-module stdlib fn
First stdlib fn that imports three other stdlib modules (std_list,
std_either, std_pair) and returns a compound polymorphic ADT tree
(Pair<List<e>, List<a>>). Stresses monomorphisation across nested
parameterised ADTs.

What shipped:
- examples/std_either_list.{ailx,ail.json}: 3 combinators —
  - lefts : forall e a. (List<Either<e, a>>) -> List<e>
  - rights : forall e a. (List<Either<e, a>>) -> List<a>
  - partition_eithers : forall e a. (List<Either<e, a>>)
                        -> Pair<List<e>, List<a>>
  lefts/rights use depth-2 nested Ctor patterns (Cons (Left l) t)
  — exercises 16a's desugar pass at a depth not reached by any
  prior fixture.
- examples/std_either_list_demo.{ailx,ail.json}: drives all three
  combinators on a five-element List<Either<Int, Int>>; expected
  output one per line: 2, 3, 2, 3.
- crates/ail/tests/e2e.rs::std_either_list_demo: e2e count 34 → 35.
- docs/JOURNAL.md: Iter 15g entry.

Compiler bug surfaced (queued as 15g-aux, not fixed):
unify_for_subst in ailang-codegen/src/lib.rs accepts $u wildcards
only on the arg side. Mixing inline (Either Left n) and (Either
Right n) in a list literal lands $u on the param side via the
outer List<a>'s binding and errors. Reduced repro: `length [Left
1, Right 10]`. Demo works around with monomorphic mkleft/mkright
helpers; workaround documented inline. Fix is a one-line symmetric
extension of the early-return.

Tests: 94/94. Stdlib: 5 modules, 27 combinators.
2026-05-07 19:57:06 +02:00

1 line
4.5 KiB
JSON

{"defs":[{"body":{"arms":[{"body":{"args":[{"name":"l","t":"var"},{"args":[{"name":"t","t":"var"}],"fn":{"name":"lefts","t":"var"},"t":"app"}],"ctor":"Cons","t":"ctor","type":"std_list.List"},"pat":{"ctor":"Cons","fields":[{"ctor":"Left","fields":[{"name":"l","p":"var"}],"p":"ctor"},{"name":"t","p":"var"}],"p":"ctor"}},{"body":{"args":[{"name":"t","t":"var"}],"fn":{"name":"lefts","t":"var"},"t":"app"},"pat":{"ctor":"Cons","fields":[{"ctor":"Right","fields":[{"p":"wild"}],"p":"ctor"},{"name":"t","p":"var"}],"p":"ctor"}},{"body":{"args":[],"ctor":"Nil","t":"ctor","type":"std_list.List"},"pat":{"p":"wild"}}],"scrutinee":{"name":"xs","t":"var"},"t":"match"},"doc":"Project the Left payloads of a list of Eithers into a List<e>. Order-preserving. Uses the 16a nested-Ctor pattern to inline the inner Either dispatch within each Cons arm; the trailing wildcard arm seals the desugar's fall-through chain into a List<e> rather than the synthetic Unit fallback.","kind":"fn","name":"lefts","params":["xs"],"type":{"body":{"effects":[],"k":"fn","params":[{"args":[{"args":[{"k":"var","name":"e"},{"k":"var","name":"a"}],"k":"con","name":"std_either.Either"}],"k":"con","name":"std_list.List"}],"ret":{"args":[{"k":"var","name":"e"}],"k":"con","name":"std_list.List"}},"k":"forall","vars":["e","a"]}},{"body":{"arms":[{"body":{"args":[{"name":"t","t":"var"}],"fn":{"name":"rights","t":"var"},"t":"app"},"pat":{"ctor":"Cons","fields":[{"ctor":"Left","fields":[{"p":"wild"}],"p":"ctor"},{"name":"t","p":"var"}],"p":"ctor"}},{"body":{"args":[{"name":"r","t":"var"},{"args":[{"name":"t","t":"var"}],"fn":{"name":"rights","t":"var"},"t":"app"}],"ctor":"Cons","t":"ctor","type":"std_list.List"},"pat":{"ctor":"Cons","fields":[{"ctor":"Right","fields":[{"name":"r","p":"var"}],"p":"ctor"},{"name":"t","p":"var"}],"p":"ctor"}},{"body":{"args":[],"ctor":"Nil","t":"ctor","type":"std_list.List"},"pat":{"p":"wild"}}],"scrutinee":{"name":"xs","t":"var"},"t":"match"},"doc":"Project the Right payloads of a list of Eithers into a List<a>. Symmetric to lefts; same nested-Ctor + wildcard-tail pattern shape.","kind":"fn","name":"rights","params":["xs"],"type":{"body":{"effects":[],"k":"fn","params":[{"args":[{"args":[{"k":"var","name":"e"},{"k":"var","name":"a"}],"k":"con","name":"std_either.Either"}],"k":"con","name":"std_list.List"}],"ret":{"args":[{"k":"var","name":"a"}],"k":"con","name":"std_list.List"}},"k":"forall","vars":["e","a"]}},{"body":{"arms":[{"body":{"args":[{"args":[],"ctor":"Nil","t":"ctor","type":"std_list.List"},{"args":[],"ctor":"Nil","t":"ctor","type":"std_list.List"}],"ctor":"MkPair","t":"ctor","type":"std_pair.Pair"},"pat":{"ctor":"Nil","fields":[],"p":"ctor"}},{"body":{"body":{"arms":[{"body":{"args":[{"args":[{"name":"l","t":"var"},{"args":[{"name":"rest","t":"var"}],"fn":{"name":"std_pair.fst","t":"var"},"t":"app"}],"ctor":"Cons","t":"ctor","type":"std_list.List"},{"args":[{"name":"rest","t":"var"}],"fn":{"name":"std_pair.snd","t":"var"},"t":"app"}],"ctor":"MkPair","t":"ctor","type":"std_pair.Pair"},"pat":{"ctor":"Left","fields":[{"name":"l","p":"var"}],"p":"ctor"}},{"body":{"args":[{"args":[{"name":"rest","t":"var"}],"fn":{"name":"std_pair.fst","t":"var"},"t":"app"},{"args":[{"name":"r","t":"var"},{"args":[{"name":"rest","t":"var"}],"fn":{"name":"std_pair.snd","t":"var"},"t":"app"}],"ctor":"Cons","t":"ctor","type":"std_list.List"}],"ctor":"MkPair","t":"ctor","type":"std_pair.Pair"},"pat":{"ctor":"Right","fields":[{"name":"r","p":"var"}],"p":"ctor"}}],"scrutinee":{"name":"h","t":"var"},"t":"match"},"name":"rest","t":"let","value":{"args":[{"name":"t","t":"var"}],"fn":{"name":"partition_eithers","t":"var"},"t":"app"}},"pat":{"ctor":"Cons","fields":[{"name":"h","p":"var"},{"name":"t","p":"var"}],"p":"ctor"}}],"scrutinee":{"name":"xs","t":"var"},"t":"match"},"doc":"Partition a list of Eithers into a Pair<List<e>, List<a>>: lefts on the left, rights on the right. Single pass via direct recursion; head dispatch is a flat match on the recursive result's projections.","kind":"fn","name":"partition_eithers","params":["xs"],"type":{"body":{"effects":[],"k":"fn","params":[{"args":[{"args":[{"k":"var","name":"e"},{"k":"var","name":"a"}],"k":"con","name":"std_either.Either"}],"k":"con","name":"std_list.List"}],"ret":{"args":[{"args":[{"k":"var","name":"e"}],"k":"con","name":"std_list.List"},{"args":[{"k":"var","name":"a"}],"k":"con","name":"std_list.List"}],"k":"con","name":"std_pair.Pair"}},"k":"forall","vars":["e","a"]}}],"imports":[{"module":"std_list"},{"module":"std_either"},{"module":"std_pair"}],"name":"std_either_list","schema":"ailang/v0"}