#lang racket ;; ::= ;; ;; ::= int ;; | bool ;; | str ;; | (-> ) ;; ;; ::= Variable reference ;; | (lambda ( : ) ) Function definition ;; | ( ) Function application ;; Env is a (Hash ) (define (fresh-env) (make-immutable-hash)) (define (valid-type? typ) (match typ ['int #t] ['str #t] ['bool #t] [(list '-> t1 t2) (and (valid-type? t1) (valid-type? t2))] [_ #f])) ;; type-check : Env -> (define (type-check env exp) (match exp [(? number? n) 'int] [(? boolean? n) 'bool] [(? string? n) 'str] [(list 'lambda (list var ': (? valid-type? typ)) body) (list '-> typ (type-check (hash-set env var typ) body))] [(list fun arg) (let ([fun-typ (type-check env fun)] [arg-typ (type-check env arg)]) (match fun-typ [(list '-> expected-arg-typ result-typ) (if (equal? arg-typ expected-arg-typ) result-typ (error "argument type mismatch"))] [else (error "expected a function")]))] [(? symbol? id) (hash-ref env id)] [_ (error "invalid expression")]))