Browse code
Reorder lens package
Ed Langley authored on 29/04/2019 07:17:45
Showing 1 changed files
Showing 1 changed files
... | ... |
@@ -4,30 +4,6 @@ |
4 | 4 |
(:export :over :set :view :make-alist-lens :make-plist-lens :make-hash-table-lens)) |
5 | 5 |
(in-package :data-lens.lenses) |
6 | 6 |
|
7 |
-(defun make-alist-lens (key) |
|
8 |
- (lambda (cb) |
|
9 |
- (lambda (alist) |
|
10 |
- (let ((old-value (serapeum:assocdr key alist))) |
|
11 |
- (cons (cons key (funcall cb old-value)) |
|
12 |
- alist))))) |
|
13 |
- |
|
14 |
-(defun make-plist-lens (key) |
|
15 |
- (lambda (cb) |
|
16 |
- (lambda (plist) |
|
17 |
- (let ((old-value (getf plist key))) |
|
18 |
- (list* key (funcall cb old-value) |
|
19 |
- plist))))) |
|
20 |
- |
|
21 |
-(defun make-hash-table-lens (key) |
|
22 |
- (lambda (cb) |
|
23 |
- (lambda (old-hash) |
|
24 |
- (let ((old-value (gethash key old-hash))) |
|
25 |
- (fw.lu:prog1-bind (new-hash (alexandria:copy-hash-table old-hash)) |
|
26 |
- (setf (gethash key new-hash) |
|
27 |
- (funcall cb old-value))))))) |
|
28 |
- |
|
29 |
-;; imagine a lens here that uses the MOP to immutably update a class... |
|
30 |
- |
|
31 | 7 |
(defun over (lens cb rec) |
32 | 8 |
"Given a lens, a callback and a record, apply the lens to the |
33 | 9 |
record, transform it by the callback and return copy of the record, |
... | ... |
@@ -73,6 +49,52 @@ contain the new value at the location focused by the lens." |
73 | 49 |
value)) |
74 | 50 |
rec)) |
75 | 51 |
|
52 |
+(defun make-alist-lens (key) |
|
53 |
+ (lambda (cb) |
|
54 |
+ (lambda (alist) |
|
55 |
+ (let ((old-value (serapeum:assocdr key alist))) |
|
56 |
+ (cons (cons key (funcall cb old-value)) |
|
57 |
+ alist))))) |
|
58 |
+ |
|
59 |
+(defun make-plist-lens (key) |
|
60 |
+ (lambda (cb) |
|
61 |
+ (lambda (plist) |
|
62 |
+ (let ((old-value (getf plist key))) |
|
63 |
+ (list* key (funcall cb old-value) |
|
64 |
+ plist))))) |
|
65 |
+ |
|
66 |
+(defun make-hash-table-lens (key) |
|
67 |
+ (lambda (cb) |
|
68 |
+ (lambda (old-hash) |
|
69 |
+ (let ((old-value (gethash key old-hash))) |
|
70 |
+ (fw.lu:prog1-bind (new-hash (alexandria:copy-hash-table old-hash)) |
|
71 |
+ (setf (gethash key new-hash) |
|
72 |
+ (funcall cb old-value))))))) |
|
73 |
+ |
|
74 |
+;; imagine a lens here that uses the MOP to immutably update a class... |
|
75 |
+(defgeneric clone (obj &rest new-initargs &key) |
|
76 |
+ (:method :around (obj &rest new-initargs &key) |
|
77 |
+ (apply #'reinitialize-instance (call-next-method) new-initargs))) |
|
78 |
+ |
|
79 |
+#+fw.demo |
|
80 |
+(progn |
|
81 |
+ (defclass foo () |
|
82 |
+ ((a :initarg :a :accessor a))) |
|
83 |
+ (defmethod clone ((obj foo) &key) |
|
84 |
+ (make-instance 'foo :a (a obj))) |
|
85 |
+ |
|
86 |
+ (defun a-lens (cb) |
|
87 |
+ (lambda (foo) |
|
88 |
+ (fw.lu:prog1-bind (new (clone foo)) |
|
89 |
+ (setf (a new) |
|
90 |
+ (funcall cb (a foo)))))) |
|
91 |
+ (view 'a-lens |
|
92 |
+ (over 'a-lens '1+ |
|
93 |
+ (set 'a-lens 2 |
|
94 |
+ (make-instance 'foo :a 1)))) #| |
|
95 |
+ ==> 3 |#) |
|
96 |
+ |
|
97 |
+ |
|
76 | 98 |
|
77 | 99 |
(defpackage :data-lens |
78 | 100 |
(:use :cl) |
... | ... |
@@ -82,8 +104,8 @@ contain the new value at the location focused by the lens." |
82 | 104 |
#:extract-key #:element #:let-fn #:juxt #:transform-tail #:slice |
83 | 105 |
#:compress-runs #:combine-matching-lists #:sorted #:applicable-when |
84 | 106 |
#:of-length #:of-min-length #:of-max-length #:transform-head |
85 |
- #:maximizing #:zipping #:applying #:transform-elt #:denest #:op |
|
86 |
- #:defalias #:<> #:<>1)) |
|
107 |
+ #:maximizing #:zipping #:applying #:splice-elt #:transform-elt #:denest |
|
108 |
+ #:op #:defalias #:<> #:<>1)) |
|
87 | 109 |
(in-package :data-lens) |
88 | 110 |
|
89 | 111 |
|
... | ... |
@@ -236,12 +258,18 @@ contain the new value at the location focused by the lens." |
236 | 258 |
(updatef (subseq result 1) |
237 | 259 |
fun))))))) |
238 | 260 |
|
239 |
-(defun-ct transform-elt (elt fun) |
|
261 |
+(defun-ct splice-elt (elt fun) |
|
240 | 262 |
(lambda (it) |
241 | 263 |
(append (subseq it 0 elt) |
242 | 264 |
(funcall fun (nth elt it)) |
243 | 265 |
(subseq it (1+ elt))))) |
244 | 266 |
|
267 |
+(defun-ct transform-elt (elt fun) |
|
268 |
+ (lambda (it) |
|
269 |
+ (append (subseq it 0 elt) |
|
270 |
+ (list (funcall fun (nth elt it))) |
|
271 |
+ (subseq it (1+ elt))))) |
|
272 |
+ |
|
245 | 273 |
(defun-ct key-transform (fun key-get key-set) |
246 | 274 |
(lambda (it) |
247 | 275 |
(let ((key-val (funcall key-get it))) |