ocaml: phase 5 HM type inference — closes lib-guest step 8 (+14 tests, 265 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 53s

OCaml-on-SX is the deferred second consumer for lib/guest/hm.sx step 8.
lib/ocaml/infer.sx assembles Algorithm W on top of the shipped algebra:

- Var: lookup + hm-instantiate.
- Fun: fresh-tv per param, auto-curried via recursion.
- App: unify against hm-arrow, fresh-tv for result.
- Let: generalize rhs over (ftv(t) - ftv(env)) — let-polymorphism.
- If: unify cond with Bool, both branches with each other.
- Op (+, =, <, etc.): builtin signatures (int*int->int monomorphic,
  =/<> polymorphic 'a->'a->bool).

Tests pass for: literals, fun x -> x : 'a -> 'a, let id ... id 5/id true,
fun f x -> f (f x) : ('a -> 'a) -> 'a -> 'a (twice).

Pending: tuples, lists, pattern matching, let-rec, modules in HM.
This commit is contained in:
2026-05-08 09:02:25 +00:00
parent 4c6790046c
commit 26863242a0
3 changed files with 276 additions and 4 deletions

View File

@@ -204,11 +204,14 @@ SX CEK evaluator (both JS and OCaml hosts)
### Phase 5 — Hindley-Milner type inference
- [ ] Algorithm W: `gen`/`inst`, `unify`, `infer-expr`, `infer-decl`.
- [ ] Type variables: `'a`, `'b`; unification with occur-check.
- [ ] Let-polymorphism: generalise at let-bindings.
- [~] Algorithm W: `gen`/`inst` from `lib/guest/hm.sx`, `unify` from
`lib/guest/match.sx`, `infer-expr` written here. Covers atoms, var,
lambda, app, let, if, op, neg, not. _(Pending: tuples, lists,
pattern matching, let-rec, modules.)_
- [x] Type variables: `'a`, `'b`; unification with occur-check (kit).
- [x] Let-polymorphism: generalise at let-bindings (kit `hm-generalize`).
- [ ] ADT types: `type 'a option = None | Some of 'a`.
- [ ] Function types, tuple types, record types.
- [~] Function types `T1 -> T2` work; tuples/records pending.
- [ ] Type signatures: `val f : int -> int` — verify against inferred type.
- [ ] Module type checking: seal against `sig` (Phase 4 stubs become real checks).
- [ ] Error reporting: position-tagged errors with expected vs actual types.
@@ -330,6 +333,17 @@ the "mother tongue" closure: OCaml → SX → OCaml. This means:
_Newest first._
- 2026-05-08 Phase 5 — Hindley-Milner type inference, paired-sequencing
consumer of `lib/guest/hm.sx` (algebra) and `lib/guest/match.sx`
(unify). `lib/ocaml/infer.sx` ships Algorithm W rules for OCaml AST:
atoms, var (instantiate), fun (auto-curry through fresh-tv), app
(unify against arrow), let (generalize over rhs), if (unify branches),
neg/not, op (treat as app of builtin). Builtin env types `+`/`-`/etc.
as monomorphic int->int->int and `=`/`<>` as polymorphic 'a->'a->bool.
Tested: literals, +1, identity polymorphism `'a -> 'a`, let-poly so
`let id = fun x -> x in id true : Bool`, `twice` infers
`('a -> 'a) -> 'a -> 'a`. Mandate satisfied: OCaml-on-SX is the
deferred second consumer for lib-guest Step 8. 265/265 (+14).
- 2026-05-08 Phase 2 — `let ... and ...` mutual recursion at top level.
Parser collects all bindings into a list, emitting `(:def-rec-mut)` or
`(:def-mut)` when there are 2+. Eval allocates a placeholder cell per