2 (and (list? x) (not (eq? (car x) 'lambda))))
6 (and (list? x) (eq? (car x) 'lambda)))
8 (define lambda-arg cadr)
9 (define lambda-body caddr)
12 (define (env-lookup env x)
13 (if (null? env) (error #f "empty env") ; it's a type equality
14 (if (eq? (caar env) x)
16 (env-lookup (cdr env) x))))
23 (set! cur-tvar (+ cur-tvar 1))
25 (string-append "t" (number->string (- cur-tvar 1))))))
27 (define (typecheck env x)
28 (display "typechecking:\n\t")
36 ((integer? x) (list '() 'int))
37 ((boolean? x) (list '() 'bool))
38 ((eq? x 'inc) (list '() '(abs int int)))
39 ((symbol? x) (list '() (env-lookup env x)))
42 (let* ((new-env (cons (cons (lambda-arg x) (fresh-tvar)) env))
43 (body-type-res (typecheck new-env (lambda-body x)))
44 (subd-env (substitute (car body-type-res) new-env)))
46 (display body-type-res)
48 (list (car body-type-res)
50 (env-lookup subd-env (lambda-arg x))
51 (cadr body-type-res)))))
54 (let* ((arg-type-res (typecheck env (cadr x)))
55 ; typecheck f with the knowledge that f : a -> x
56 (func-type-res (typecheck env (car x)))
57 (func-type (cadr func-type-res))
62 (new-env (substitute c env))
63 (resolved-func-type (env-lookup new-env (car x))))
69 (display resolved-func-type)
71 (display arg-type-res)
73 (if (abs? resolved-func-type)
75 (unify (cadr arg-type-res)
76 (cadr resolved-func-type)))
77 (caddr resolved-func-type))
78 (error #f "wah")))))))
79 (display "result of ")
90 (and (list? t) (eq? (car t) 'abs)))
93 (and (not (list? t)) (not (concrete? t)) (symbol? t)))
101 ; returns a list of pairs of constraints
103 (cond ((eq? a b) '())
104 ((or (tvar? a) (tvar? b)) (list (cons a b)))
105 ((and (abs? a) (abs? b))
106 (append (unify (cadr a) (cadr b))
107 (unify (caddr a) (caddr b))))
108 (else (error #f "could not unify"))))
110 ; takes a list of constraints and a type environment, and makes it work
111 (define (substitute c env)
112 (let ((go (lambda (x) (let ((tv (cdr x))
122 (cond ((eq? a (car y)) (cdr y))
123 ((eq? a (cdr y)) (car y))