ocaml: phase 5 HM let-rec + cons / append op types (+6 tests, 357 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 28s

ocaml-infer-let-rec pre-binds the function name to a fresh tv before
inferring rhs (which may recursively call the name), unifies the
inferred rhs type with the tv, generalizes, then infers body.

Builtin env types :: : 'a -> 'a list -> 'a list and @ : 'a list ->
'a list -> 'a list — needed because :op compiles to (:app (:app (:var
OP) L) R) and previously these var lookups failed.

Examples now infer:
  let rec fact n = if ... in fact : Int -> Int
  let rec len lst = ... in len    : 'a list -> Int
  let rec map f xs = ... in map   : ('a -> 'b) -> 'a list -> 'b list
  1 :: [2; 3]                      : Int list
  let rec sum lst = ... in sum [1;2;3] : Int

Scoreboard refreshed: 358/358 across 14 suites.
This commit is contained in:
2026-05-08 13:08:51 +00:00
parent 81247eb6ea
commit 5bc7895ce0
5 changed files with 86 additions and 16 deletions

View File

@@ -872,6 +872,20 @@ cat > "$TMPFILE" << 'EPOCHS'
(epoch 1906)
(eval "(ocaml-type-of \"fun o -> match o with | None -> 0 | Some n -> n\")")
;; ── HM let-rec inference + cons / append ──────────────────────
(epoch 2000)
(eval "(ocaml-type-of \"let rec fact n = if n = 0 then 1 else n * fact (n - 1) in fact\")")
(epoch 2001)
(eval "(ocaml-type-of \"let rec len lst = match lst with | [] -> 0 | _ :: t -> 1 + len t in len\")")
(epoch 2002)
(eval "(ocaml-type-of \"let rec map f xs = match xs with | [] -> [] | h :: t -> f h :: map f t in map\")")
(epoch 2003)
(eval "(ocaml-type-of \"1 :: [2; 3]\")")
(epoch 2004)
(eval "(ocaml-type-of \"[1] @ [2; 3]\")")
(epoch 2005)
(eval "(ocaml-type-of \"let rec sum lst = match lst with | [] -> 0 | h :: t -> h + sum t in sum [1; 2; 3]\")")
EPOCHS
OUTPUT=$(timeout 180 "$SX_SERVER" < "$TMPFILE" 2>/dev/null)
@@ -1379,6 +1393,14 @@ check 1904 "fun x -> Some x" ' option'
check 1905 "match Some/None -> Int" '"Int"'
check 1906 "Int option -> Int" '"Int option -> Int"'
# ── HM let-rec + :: / @ ─────────────────────────────────────────
check 2000 "type fact" '"Int -> Int"'
check 2001 "type len" 'list -> Int'
check 2002 "type map" 'list -> '
check 2003 "type 1::list" '"Int list"'
check 2004 "type [1] @ [2;3]" '"Int list"'
check 2005 "type sum" '"Int"'
TOTAL=$((PASS + FAIL))
if [ $FAIL -eq 0 ]; then
echo "ok $PASS/$TOTAL OCaml-on-SX tests passed"