Browse code
feat: add • compose operator
Ed Langley authored on 30/09/2020 22:48:03
Showing 2 changed files
Showing 2 changed files
... | ... |
@@ -93,10 +93,10 @@ operator): |
93 | 93 |
|
94 | 94 |
(== (view lens (set lens value rec)) |
95 | 95 |
value) |
96 |
- |
|
96 |
+ |
|
97 | 97 |
(== (set lens (view lens rec) rec) |
98 | 98 |
rec) |
99 |
- |
|
99 |
+ |
|
100 | 100 |
(== (set lens value2 (set lens value1 rec)) |
101 | 101 |
(set lens value2 rec)) |
102 | 102 |
|
... | ... |
@@ -234,11 +234,12 @@ contain the new value at the location focused by the lens." |
234 | 234 |
#:compress-runs #:combine-matching-lists #:sorted #:applicable-when |
235 | 235 |
#:of-length #:of-min-length #:of-max-length #:transform-head |
236 | 236 |
#:maximizing #:zipping #:applying #:splice-elt #:transform-elt #:denest |
237 |
- #:op #:defalias #:<> #:<>1)) |
|
237 |
+ #:op #:defalias #:<> #:<>1 |
|
238 |
+ #:•)) |
|
238 | 239 |
(in-package :data-lens) |
239 | 240 |
|
240 | 241 |
|
241 |
-(declaim |
|
242 |
+(declaim |
|
242 | 243 |
(inline data-lens:over data-lens:transform-tail |
243 | 244 |
data-lens:applicable-when data-lens:of-min-length |
244 | 245 |
data-lens:on data-lens:over data-lens:slice |
... | ... |
@@ -524,3 +525,5 @@ contain the new value at the location focused by the lens." |
524 | 525 |
|
525 | 526 |
(defmacro <>1 (&rest funs) |
526 | 527 |
`(alexandria:compose ,@funs)) |
528 |
+(defmacro • (&rest funs) |
|
529 |
+ `(alexandria:compose ,@funs)) |
527 | 530 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,53 @@ |
1 |
+(defpackage :data-lens.wrapped-sequence |
|
2 |
+ (:use :cl ) |
|
3 |
+ (:export )) |
|
4 |
+(in-package :data-lens.wrapped-sequence) |
|
5 |
+ |
|
6 |
+(defgeneric underlying (wrapper) |
|
7 |
+ (:documentation "Return the underlying object of a wrapper")) |
|
8 |
+ |
|
9 |
+(defclass tagged-sequence (standard-object sequence) |
|
10 |
+ ((%underlying-sequence :initarg :underlying :accessor underlying) |
|
11 |
+ (%key-fn :initarg :key :reader key) |
|
12 |
+ (%invert-key :initarg :invert-key :reader invert-key))) |
|
13 |
+ |
|
14 |
+(defmethod sb-sequence:length ((sequence tagged-sequence)) |
|
15 |
+ (length (underlying sequence))) |
|
16 |
+ |
|
17 |
+(defmethod sb-sequence:elt ((sequence tagged-sequence) index) |
|
18 |
+ (funcall (key sequence) |
|
19 |
+ (elt (underlying sequence) |
|
20 |
+ index))) |
|
21 |
+ |
|
22 |
+(defmethod (setf sb-sequence:elt) (new-value (sequence tagged-sequence) index) |
|
23 |
+ (setf (elt (underlying sequence) |
|
24 |
+ index) |
|
25 |
+ (funcall (invert-key sequence) |
|
26 |
+ (elt (underlying sequence) |
|
27 |
+ index) |
|
28 |
+ new-value))) |
|
29 |
+ |
|
30 |
+(defmethod sb-sequence:adjust-sequence ((sequence tagged-sequence) length |
|
31 |
+ &rest r |
|
32 |
+ &key initial-element initial-contents) |
|
33 |
+ (declare (ignore initial-element initial-contents)) |
|
34 |
+ (make-instance 'tagged-sequence |
|
35 |
+ :underlying (apply #'sb-sequence:adjust-sequence |
|
36 |
+ (copy-seq (underlying sequence)) length |
|
37 |
+ r) |
|
38 |
+ :key-fn (key sequence) |
|
39 |
+ :invert-key (invert-key sequence))) |
|
40 |
+ |
|
41 |
+(defmethod sb-sequence:make-sequence-like |
|
42 |
+ ((sequence tagged-sequence) length &rest r) |
|
43 |
+ (apply #'sb-sequence:adjust-sequence sequence length r)) |
|
44 |
+ |
|
45 |
+(defun wrap-sequence (seq key-fn invert-key-fn) |
|
46 |
+ (if invert-key-fn |
|
47 |
+ (make-instance 'tagged-sequence |
|
48 |
+ :underlying seq |
|
49 |
+ :key key-fn |
|
50 |
+ :invert-key invert-key-fn) |
|
51 |
+ (make-instance 'tagged-sequence |
|
52 |
+ :underlying seq |
|
53 |
+ :key key-fn))) |