git.fiddlerwoaroof.com
Browse code

feat: add • compose operator

Ed Langley authored on 30/09/2020 22:48:03
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)))