-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathenv.rkt
83 lines (67 loc) · 1.85 KB
/
env.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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#lang racket
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Environments
;;
;; A simple implementation of environments as association lists.
(provide empty-env empty-env?
lookup lookup? bound? extend-env extend-env*
join-env env->list env-domain env-range
env-restrict
env-map
filter-env)
(define empty-env '())
(define empty-env? null?)
(define lookup
(lambda (env x)
(match (assq x env)
[#f (error 'lookup "no binding for ~s (~a)" x env)]
[(cons _ b) b])))
(define lookup?
(lambda (env x)
(match (assq x env)
[#f #f]
[(cons _ b) b])))
(define bound?
(lambda (env x)
(match (assq x env)
[#f #f]
[_ #t])))
(define extend-env
(lambda (env x v)
(cons (cons x v) env)))
(define extend-env*
(lambda (env xs vs)
(append (map cons xs vs) env)))
(define join-env
(lambda (env newenv)
(append newenv env)))
(define env->list
(lambda (env)
(let loop ([env env] [seen '()])
(cond [(null? env) env]
[(memq (caar env) seen) (loop (cdr env) seen)]
[else (let ([d (loop (cdr env) (cons (caar env) seen))])
(if (eq? d (cdr env))
env
(cons (car env) d)))]))))
(define env-domain
(lambda (env)
(map car (env->list env))))
(define env-range
(lambda (env)
(map cdr (env->list env))))
(define env-restrict
(lambda (env domain)
(filter
(match-lambda [(cons x v) (memq x domain)])
(env->list env))))
(define env-map
(lambda (f env)
(map (match-lambda ((cons x v) (cons x (f x v))))
(env->list env))))
(define filter-env
(lambda (f env)
(let loop ([env (env->list env)])
(cond [(null? env) env]
[(f (caar env)) (cons (car env) (loop (cdr env)))]
[else (loop (cdr env))]))))