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
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:
@@ -30,10 +30,13 @@ cat > "$TMPFILE" << 'EPOCHS'
|
||||
(load "lib/guest/lex.sx")
|
||||
(load "lib/guest/prefix.sx")
|
||||
(load "lib/guest/pratt.sx")
|
||||
(load "lib/guest/match.sx")
|
||||
(load "lib/guest/hm.sx")
|
||||
(load "lib/ocaml/tokenizer.sx")
|
||||
(load "lib/ocaml/parser.sx")
|
||||
(load "lib/ocaml/eval.sx")
|
||||
(load "lib/ocaml/runtime.sx")
|
||||
(load "lib/ocaml/infer.sx")
|
||||
(load "lib/ocaml/tests/tokenize.sx")
|
||||
(eval "(ocaml-load-stdlib!)")
|
||||
|
||||
@@ -639,6 +642,36 @@ cat > "$TMPFILE" << 'EPOCHS'
|
||||
(epoch 852)
|
||||
(eval "(ocaml-run-program \"let x = 1 and y = 2;; x + y\")")
|
||||
|
||||
;; ── Phase 5: Hindley-Milner type inference ────────────────────
|
||||
(epoch 900)
|
||||
(eval "(ocaml-type-of \"42\")")
|
||||
(epoch 901)
|
||||
(eval "(ocaml-type-of \"true\")")
|
||||
(epoch 902)
|
||||
(eval "(ocaml-type-of \"\\\"hi\\\"\")")
|
||||
(epoch 903)
|
||||
(eval "(ocaml-type-of \"1 + 2\")")
|
||||
(epoch 904)
|
||||
(eval "(ocaml-type-of \"fun x -> x + 1\")")
|
||||
(epoch 905)
|
||||
(eval "(ocaml-type-of \"fun x -> x\")")
|
||||
(epoch 906)
|
||||
(eval "(ocaml-type-of \"fun x y -> x + y\")")
|
||||
(epoch 907)
|
||||
(eval "(ocaml-type-of \"let f x = x + 1 in f 10\")")
|
||||
(epoch 908)
|
||||
(eval "(ocaml-type-of \"let id = fun x -> x in id 5\")")
|
||||
(epoch 909)
|
||||
(eval "(ocaml-type-of \"let id = fun x -> x in id true\")")
|
||||
(epoch 910)
|
||||
(eval "(ocaml-type-of \"if true then 1 else 2\")")
|
||||
(epoch 911)
|
||||
(eval "(ocaml-type-of \"fun f -> fun x -> f (f x)\")")
|
||||
(epoch 912)
|
||||
(eval "(ocaml-type-of \"fun b -> if b then 1 else 0\")")
|
||||
(epoch 913)
|
||||
(eval "(ocaml-type-of \"not true\")")
|
||||
|
||||
EPOCHS
|
||||
|
||||
OUTPUT=$(timeout 60 "$SX_SERVER" < "$TMPFILE" 2>/dev/null)
|
||||
@@ -1016,6 +1049,22 @@ check 850 "even 10 (mutual rec)" 'true'
|
||||
check 851 "odd 7 (mutual rec)" 'true'
|
||||
check 852 "let x = 1 and y = 2" '3'
|
||||
|
||||
# ── Phase 5: Hindley-Milner type inference ────────────────────
|
||||
check 900 "type 42 = Int" '"Int"'
|
||||
check 901 "type true = Bool" '"Bool"'
|
||||
check 902 'type string lit' '"String"'
|
||||
check 903 "type 1+2 = Int" '"Int"'
|
||||
check 904 "type fun x->x+1 = Int->Int" '"Int -> Int"'
|
||||
check 905 "type fun x->x = poly" ' -> '
|
||||
check 906 "type fun x y->x+y" '"Int -> Int -> Int"'
|
||||
check 907 "type let f x=x+1 in f 10" '"Int"'
|
||||
check 908 "type let id; id 5" '"Int"'
|
||||
check 909 "type let id; id true" '"Bool"'
|
||||
check 910 "type if/then/else" '"Int"'
|
||||
check 911 "type twice" ' -> '
|
||||
check 912 "type bool branch" '"Bool -> Int"'
|
||||
check 913 "type not true" '"Bool"'
|
||||
|
||||
TOTAL=$((PASS + FAIL))
|
||||
if [ $FAIL -eq 0 ]; then
|
||||
echo "ok $PASS/$TOTAL OCaml-on-SX tests passed"
|
||||
|
||||
Reference in New Issue
Block a user