de674c4d0b
Fix the codegen asymmetry that 15g surfaced. unify_for_subst had an arg-side-only early-return for $u-prefixed synth wildcards. The function's prev-binding recursion can swap a $u from arg into param position when re-unifying a previously-bound type against a fresh arg. Reduced repro: `length [Left 1, Right 10]` — `a` first binds to `Either<Int, $u>`, then the recursive unification against `Either<$u, Int>` lands $u in param-pos[1] and falls through to the catch-all error. Fix is three lines: add a symmetric $u early-return for param side. $u is a synth-only wildcard regardless of which side it ends up on after the prev-binding swap. Doc comment expanded to record the origin and justification. std_either_list_demo refactored: mkleft/mkright workaround helpers removed; the list is now constructed inline by mixing (term-ctor std_either.Either Left 1) and (... Right 10) directly. Same expected output (2, 3, 2, 3); the demo doubles as the 15g-aux regression fixture. Tests: 94/94, unchanged. The fix expanded what compiles without changing observable behaviour for any prior fixture.
1 line
4.8 KiB
JSON
1 line
4.8 KiB
JSON
{"defs":[{"body":{"lhs":{"args":[{"args":[{"args":[{"args":[{"args":[{"lit":{"kind":"int","value":1},"t":"lit"}],"ctor":"Left","t":"ctor","type":"std_either.Either"},{"args":[{"args":[{"lit":{"kind":"int","value":10},"t":"lit"}],"ctor":"Right","t":"ctor","type":"std_either.Either"},{"args":[{"args":[{"lit":{"kind":"int","value":2},"t":"lit"}],"ctor":"Left","t":"ctor","type":"std_either.Either"},{"args":[{"args":[{"lit":{"kind":"int","value":20},"t":"lit"}],"ctor":"Right","t":"ctor","type":"std_either.Either"},{"args":[{"args":[{"lit":{"kind":"int","value":30},"t":"lit"}],"ctor":"Right","t":"ctor","type":"std_either.Either"},{"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"}],"fn":{"name":"std_either_list.lefts","t":"var"},"t":"app"}],"fn":{"name":"std_list.length","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"lhs":{"args":[{"args":[{"args":[{"args":[{"args":[{"lit":{"kind":"int","value":1},"t":"lit"}],"ctor":"Left","t":"ctor","type":"std_either.Either"},{"args":[{"args":[{"lit":{"kind":"int","value":10},"t":"lit"}],"ctor":"Right","t":"ctor","type":"std_either.Either"},{"args":[{"args":[{"lit":{"kind":"int","value":2},"t":"lit"}],"ctor":"Left","t":"ctor","type":"std_either.Either"},{"args":[{"args":[{"lit":{"kind":"int","value":20},"t":"lit"}],"ctor":"Right","t":"ctor","type":"std_either.Either"},{"args":[{"args":[{"lit":{"kind":"int","value":30},"t":"lit"}],"ctor":"Right","t":"ctor","type":"std_either.Either"},{"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"}],"fn":{"name":"std_either_list.rights","t":"var"},"t":"app"}],"fn":{"name":"std_list.length","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"lhs":{"args":[{"args":[{"args":[{"args":[{"args":[{"args":[{"lit":{"kind":"int","value":1},"t":"lit"}],"ctor":"Left","t":"ctor","type":"std_either.Either"},{"args":[{"args":[{"lit":{"kind":"int","value":10},"t":"lit"}],"ctor":"Right","t":"ctor","type":"std_either.Either"},{"args":[{"args":[{"lit":{"kind":"int","value":2},"t":"lit"}],"ctor":"Left","t":"ctor","type":"std_either.Either"},{"args":[{"args":[{"lit":{"kind":"int","value":20},"t":"lit"}],"ctor":"Right","t":"ctor","type":"std_either.Either"},{"args":[{"args":[{"lit":{"kind":"int","value":30},"t":"lit"}],"ctor":"Right","t":"ctor","type":"std_either.Either"},{"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"}],"fn":{"name":"std_either_list.partition_eithers","t":"var"},"t":"app"}],"fn":{"name":"std_pair.fst","t":"var"},"t":"app"}],"fn":{"name":"std_list.length","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"args":[{"args":[{"args":[{"args":[{"args":[{"args":[{"lit":{"kind":"int","value":1},"t":"lit"}],"ctor":"Left","t":"ctor","type":"std_either.Either"},{"args":[{"args":[{"lit":{"kind":"int","value":10},"t":"lit"}],"ctor":"Right","t":"ctor","type":"std_either.Either"},{"args":[{"args":[{"lit":{"kind":"int","value":2},"t":"lit"}],"ctor":"Left","t":"ctor","type":"std_either.Either"},{"args":[{"args":[{"lit":{"kind":"int","value":20},"t":"lit"}],"ctor":"Right","t":"ctor","type":"std_either.Either"},{"args":[{"args":[{"lit":{"kind":"int","value":30},"t":"lit"}],"ctor":"Right","t":"ctor","type":"std_either.Either"},{"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"}],"fn":{"name":"std_either_list.partition_eithers","t":"var"},"t":"app"}],"fn":{"name":"std_pair.snd","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"},"doc":"Drive lefts, rights, and partition_eithers on the same five-element List<Either<Int, Int>> (Left 1, Right 10, Left 2, Right 20, Right 30). Expected output (one per line): 2, 3, 2, 3.","kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[{"module":"std_list"},{"module":"std_either"},{"module":"std_pair"},{"module":"std_either_list"}],"name":"std_either_list_demo","schema":"ailang/v0"} |