forked from ijp/ijputils
-
Notifications
You must be signed in to change notification settings - Fork 0
/
lens.sls
74 lines (63 loc) · 1.42 KB
/
lens.sls
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
#!r6rs
;;; Lens toy based on Asymmetric Lenses in Scala by Tony Morris
;;;; Lens laws
;;;
;;; law 1.
;;; (get lens (set lens r f)) == f
;;;
;;; law 2.
;;; (set lens r (get lens r)) == r
;;;
;;; law 3.
;;; (set lens (set lens r f2) f1) == (set lens r f1)
(library (ijputils lens)
(export make-lens
lens?
get
set
modify
compose-lens
id-lens
product-lens
car-lens
cdr-lens
)
(import (rnrs))
;; maybe make it a codatatype rather than a record?
(define-record-type lens
(fields
(immutable get get*)
(immutable set set*)))
(define (get lens obj)
((get* lens) obj))
(define (set lens obj val)
((set* lens) obj val))
(define (modify lens func)
(lambda (obj)
(set lens obj (func (get lens obj)))))
(define (compose-lens lens2 lens1)
(make-lens
(lambda (obj) (get lens2 (get lens1 obj)))
(lambda (obj val) (set lens1 obj
(set lens2 (get lens1 obj) val)))))
(define id-lens
(make-lens (lambda (x) x) (lambda (x y) x)))
(define (product-lens l1 l2)
(make-lens
(lambda (obj)
(cons (get l1 (car obj))
(get l2 (cdr obj))))
(lambda (obj val)
(cons (set l1 (car obj) (car val))
(set l2 (cdr obj) (cdr val))))))
(define car-lens
(make-lens
car
(lambda (pair v)
(cons v (cdr pair)))))
(define cdr-lens
(make-lens
cdr
(lambda (pair new)
(cons (car pair) new))))
)