ocaml: phase 5 HM tuple + list types (+7 tests, 326 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 29s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 29s
Tuple type (hm-con "*" TYPES); list type (hm-con "list" (TYPE)). ocaml-infer-tuple threads substitution through each item left-to-right. ocaml-infer-list unifies all items with a fresh 'a (giving 'a list for empty []). Pretty-printer renders 'Int * Int' for tuples and 'Int list' for lists, matching standard OCaml notation. Examples: fun x y -> (x, y) : 'a -> 'b -> 'a * 'b fun x -> [x; x] : 'a -> 'a list [] : 'a list
This commit is contained in:
@@ -145,6 +145,56 @@
|
||||
{:subst sf
|
||||
:type (hm-apply sf te)}))))))))))))
|
||||
|
||||
;; Tuple type: (hm-con "*" (list T1 T2 ...)).
|
||||
(define ocaml-hm-tuple
|
||||
(fn (types) (hm-con "*" types)))
|
||||
|
||||
;; List type: (hm-con "list" (list ELEM)).
|
||||
(define ocaml-hm-list
|
||||
(fn (elem) (hm-con "list" (list elem))))
|
||||
|
||||
(define ocaml-infer-tuple
|
||||
(fn (items env counter)
|
||||
(let ((subst {}) (types (list)))
|
||||
(begin
|
||||
(define loop
|
||||
(fn (xs env-cur)
|
||||
(when (not (= xs (list)))
|
||||
(let ((r (ocaml-infer (first xs) env-cur counter)))
|
||||
(let ((s (get r :subst)) (t (get r :type)))
|
||||
(begin
|
||||
(set! subst (hm-compose s subst))
|
||||
(append! types t)
|
||||
(loop (rest xs) (hm-apply-env s env-cur))))))))
|
||||
(loop items env)
|
||||
{:subst subst
|
||||
:type (ocaml-hm-tuple
|
||||
(map (fn (t) (hm-apply subst t)) types))}))))
|
||||
|
||||
(define ocaml-infer-list
|
||||
(fn (items env counter)
|
||||
(cond
|
||||
((= (len items) 0)
|
||||
{:subst {} :type (ocaml-hm-list (hm-fresh-tv counter))})
|
||||
(else
|
||||
(let ((subst {}) (elem-tv (hm-fresh-tv counter)))
|
||||
(begin
|
||||
(define loop
|
||||
(fn (xs env-cur)
|
||||
(when (not (= xs (list)))
|
||||
(let ((r (ocaml-infer (first xs) env-cur counter)))
|
||||
(let ((s (get r :subst)) (t (get r :type)))
|
||||
(let ((s2 (ocaml-hm-unify
|
||||
(hm-apply s elem-tv)
|
||||
t
|
||||
(hm-compose s subst))))
|
||||
(begin
|
||||
(set! subst s2)
|
||||
(loop (rest xs) (hm-apply-env s2 env-cur)))))))))
|
||||
(loop items env)
|
||||
{:subst subst
|
||||
:type (ocaml-hm-list (hm-apply subst elem-tv))}))))))
|
||||
|
||||
(set! ocaml-infer
|
||||
(fn (expr env counter)
|
||||
(let ((tag (nth expr 0)))
|
||||
@@ -162,6 +212,8 @@
|
||||
(nth expr 3) (nth expr 4) env counter))
|
||||
((= tag "if") (ocaml-infer-if (nth expr 1) (nth expr 2)
|
||||
(nth expr 3) env counter))
|
||||
((= tag "tuple") (ocaml-infer-tuple (rest expr) env counter))
|
||||
((= tag "list") (ocaml-infer-list (rest expr) env counter))
|
||||
((= tag "neg")
|
||||
(let ((r (ocaml-infer (nth expr 1) env counter)))
|
||||
(let ((s (get r :subst)) (t (get r :type)))
|
||||
@@ -205,5 +257,11 @@
|
||||
(str "(" (ocaml-hm-format-type a) ")"))
|
||||
(else (ocaml-hm-format-type a)))
|
||||
" -> " (ocaml-hm-format-type b))))
|
||||
((= head "*")
|
||||
(let ((parts (map ocaml-hm-format-type args)))
|
||||
(join " * " parts)))
|
||||
((= head "list")
|
||||
(let ((elem (ocaml-hm-format-type (nth args 0))))
|
||||
(str elem " list")))
|
||||
(else head))))
|
||||
(else (str t)))))
|
||||
|
||||
Reference in New Issue
Block a user