Substitute constraints after recursive call
authorLuke Lau <luke_lau@icloud.com>
Mon, 29 Jul 2019 12:55:23 +0000 (13:55 +0100)
committerLuke Lau <luke_lau@icloud.com>
Mon, 29 Jul 2019 12:55:23 +0000 (13:55 +0100)
Now it typechecks! Also fix type-equal? being too lenient

typecheck.scm

index a767ed07fb1c2244819c0bcbbb2539ff9ecc12bf..219b010202a7f7a0127847e8372ea7e064a05efb 100644 (file)
                 (let* [(func-type (env-lookup env (car x)))
                        (return-type (fresh-tvar))
                        (other-func-type `(abs ,func-type ,return-type))
-                       (cs (~ func-type other-func-type))]
-                  (list cs return-type))
+                       (cs (~ func-type other-func-type))
+                       (resolved-return-type (substitute cs return-type))]
+                  (list cs resolved-return-type))
 
                                        ; regular function
                 (let* ((arg-type-res (check env (cadr x)))
 
                                        ; TODO: what's the most appropriate substitution?
                                        ; should all constraints just be limited to a pair?
+                                       ; this is currently horrific and i don't know what im doing.
+                                       ; should probably use ast-find here or during consolidation
+                                       ; to detect substitutions more than one layer deep
+                                       ; e.g. (abs t1 int) ~ (abs bool int)
+                                       ; substituting these constraints with t1 should resolve t1 with bool
 (define (substitute cs t)
                                        ; gets the first concrete type
                                        ; otherwise returns the last type variable
 
+                                       ; removes t itself from cs, to prevent infinite recursion
   (define cs-without-t
     (map (lambda (c)
           (filter (lambda (x) (not (eqv? t x))) c))
              (lambda (acc c)
                (if (tvar? c) acc #f))]
             [test (lambda (acc c)
-                    (and acc (fold-left test-kind #t c)))])
+                    (and acc
+                         (fold-left test-kind #t c) ; check only tvar substitutions
+                         (<= (length c) 2)))])      ; check maximum 2 subs per equality group
          (fold-left test #t cs)))))
 
                                        ; input: a list of binds ((x . y) (y . 3))