This repository has been archived by the owner on Feb 1, 2021. It is now read-only.
generated from dannypsnl-fork/racket-project
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcore.rkt
55 lines (47 loc) · 1.6 KB
/
core.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#lang racket/base
(require racket/match)
(require "substmap.rkt")
(provide (struct-out Constructor))
(struct Constructor (typ) #:transparent)
(provide (struct-out Function))
(struct Function (param-name* param-typ* typ expr) #:transparent)
(provide (struct-out Value))
(struct Value (v typ)
#:methods gen:custom-write
[(define (write-proc value port mode)
(fprintf port "~a" (Value-v value)))]
#:transparent)
(provide replace-occur)
(define (replace-occur #:in in #:occur occurs)
(match in
[`(,e* ...)
(map (λ (e) (replace-occur #:in e #:occur occurs)) e*)]
[v (let ([new-v (hash-ref occurs v #f)])
(if new-v new-v v))]))
(define (full-expand exp occurs)
(match exp
[`(,e* ...)
(map (λ (e) (full-expand e occurs)) e*)]
[v (let ([new-v (hash-ref occurs v #f)])
(if new-v (full-expand new-v occurs) v))]))
(provide unify)
(define (unify t1 t2 #:subst [subst (make-subst)])
(match* {t1 t2}
[{(? FreeVar?) _} (subst-set! subst t1 t2)]
[{_ (? FreeVar?)} (unify t2 t1 #:subst subst)]
[{`(,t1* ...) `(,t2* ...)}
(map (λ (t1 t2) (unify t1 t2 #:subst subst))
t1* t2*)]
[{_ _}
(unless (equal? t1 t2)
(error 'semantic "type mismatched, expected: `~a`, but got: `~a`" t1 t2))])
(full-expand t1 (subst-resolve subst)))
(module+ test
(require rackunit)
(check-equal? (unify (FreeVar 'c 'U) '(-> A B)) '(-> A B))
(let ([s (make-subst)])
(unify (FreeVar 'a 'U) 'A #:subst s)
(unify (FreeVar 'b 'U) 'B #:subst s)
(check-equal?
(unify (FreeVar 'c 'U) `(-> ,(FreeVar 'a 'U) ,(FreeVar 'b 'U)) #:subst s)
'(-> A B))))