mirror of
https://github.com/fiddlerwoaroof/data-lens.git
synced 2025-11-08 18:26:32 +00:00
Compare commits
6 Commits
7618f95482
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 184464a017 | |||
| ffe67ab084 | |||
| f76e0e0320 | |||
| d52023f9f4 | |||
| f9d091759c | |||
| 742a155e91 |
@ -17,9 +17,9 @@
|
|||||||
(data-lens.transducers:transducer-lambda
|
(data-lens.transducers:transducer-lambda
|
||||||
((acc next)
|
((acc next)
|
||||||
(fset:with acc next))))
|
(fset:with acc next))))
|
||||||
(defmethod data-lens:functionalize ((it fset:set))
|
(defmethod data-lens:functionalize ((set fset:set))
|
||||||
(lambda (key)
|
(lambda (it)
|
||||||
(nth-value 1 (fset:lookup it key))))
|
(fset:contains? set it)))
|
||||||
(defmethod data-lens:extract-key ((it fset:set) key)
|
(defmethod data-lens:extract-key ((it fset:set) key)
|
||||||
(nth-value 1 (fset:lookup it key)))
|
(nth-value 1 (fset:lookup it key)))
|
||||||
(defun make-set-lens (item)
|
(defun make-set-lens (item)
|
||||||
@ -63,6 +63,11 @@
|
|||||||
rec))
|
rec))
|
||||||
|
|
||||||
|
|
||||||
|
(defmethod data-lens.transducers.internals:reduce-generic ((map fset:map) (func function) init)
|
||||||
|
(fset:reduce (lambda (acc k v)
|
||||||
|
(funcall func acc (list k v)))
|
||||||
|
map
|
||||||
|
:initial-value init))
|
||||||
(defmethod data-lens.transducers.internals:builder-for-input ((map fset:map))
|
(defmethod data-lens.transducers.internals:builder-for-input ((map fset:map))
|
||||||
(values 'fset-map-builder
|
(values 'fset-map-builder
|
||||||
map))
|
map))
|
||||||
@ -104,7 +109,9 @@
|
|||||||
m)))
|
m)))
|
||||||
(defun make-bag-lens (item)
|
(defun make-bag-lens (item)
|
||||||
(make-set-lens item))
|
(make-set-lens item))
|
||||||
|
|
||||||
(defmethod data-lens.lenses:generic-lens ((rec fset:bag) cb loc)
|
(defmethod data-lens.lenses:generic-lens ((rec fset:bag) cb loc)
|
||||||
(funcall (funcall (make-set-lens loc)
|
(funcall (funcall (make-set-lens loc)
|
||||||
cb)
|
cb)
|
||||||
rec))
|
rec))
|
||||||
|
|
||||||
|
|||||||
16
optics.lisp
16
optics.lisp
@ -217,3 +217,19 @@ contain the new value at the location focused by the lens."
|
|||||||
(set 'a-lens 2
|
(set 'a-lens 2
|
||||||
(make-instance 'foo :a 1)))) #|
|
(make-instance 'foo :a 1)))) #|
|
||||||
==> 3 |#)
|
==> 3 |#)
|
||||||
|
|
||||||
|
(defgeneric generic-lens (rec cb loc)
|
||||||
|
(:method ((rec hash-table) cb loc)
|
||||||
|
(funcall (funcall (make-hash-table-lens loc)
|
||||||
|
cb)
|
||||||
|
rec))
|
||||||
|
(:method ((rec vector) cb loc)
|
||||||
|
(funcall (funcall (make-list-lens loc)
|
||||||
|
cb)
|
||||||
|
rec)))
|
||||||
|
|
||||||
|
(defun lens (loc)
|
||||||
|
"extensible lens using a multimethod for internal implementation"
|
||||||
|
(lambda (cb)
|
||||||
|
(lambda (rec)
|
||||||
|
(generic-lens rec cb loc))))
|
||||||
|
|||||||
@ -237,6 +237,22 @@
|
|||||||
'<
|
'<
|
||||||
:key 'car))))
|
:key 'car))))
|
||||||
|
|
||||||
|
(5am:is (equalp #(1 2 3 4)
|
||||||
|
(data-lens.transducers:into #() '(1 2 3 4)))
|
||||||
|
"~s can be used to convert one type into another without a transducer"
|
||||||
|
'data-lens.transducers:into)
|
||||||
|
|
||||||
|
(5am:is (equalp #(1 2 4)
|
||||||
|
(handler-bind ((simple-error #'continue))
|
||||||
|
(data-lens.transducers:into #()
|
||||||
|
(data-lens.transducers:mapping
|
||||||
|
(lambda (it)
|
||||||
|
(if (= it 3)
|
||||||
|
(error "fail")
|
||||||
|
it)))
|
||||||
|
'(1 2 3 4))))
|
||||||
|
"transducers provide a continue restart")
|
||||||
|
|
||||||
(loop for type in '(vector list)
|
(loop for type in '(vector list)
|
||||||
do (5am:is (equalp #(1 2 3 4 5 6)
|
do (5am:is (equalp #(1 2 3 4 5 6)
|
||||||
(data-lens.transducers:into #(1 2 3)
|
(data-lens.transducers:into #(1 2 3)
|
||||||
|
|||||||
@ -16,12 +16,6 @@
|
|||||||
seq)
|
seq)
|
||||||
acc)))
|
acc)))
|
||||||
|
|
||||||
#+(or)
|
|
||||||
(defun document (&rest strings)
|
|
||||||
(serapeum:string-join strings #.(format nil "~2%")))
|
|
||||||
|
|
||||||
(defgeneric init (client))
|
|
||||||
(defgeneric stepper (client))
|
|
||||||
(defmacro transducer-lambda (&body (((two-arg-acc two-arg-next) &body two-arg-body)
|
(defmacro transducer-lambda (&body (((two-arg-acc two-arg-next) &body two-arg-body)
|
||||||
&optional (((one-arg-arg) &body one-arg-body)
|
&optional (((one-arg-arg) &body one-arg-body)
|
||||||
'((it) it))))
|
'((it) it))))
|
||||||
@ -33,16 +27,39 @@
|
|||||||
,@two-arg-body)
|
,@two-arg-body)
|
||||||
(let ((,one-arg-arg ,arg1))
|
(let ((,one-arg-arg ,arg1))
|
||||||
,@one-arg-body)))))
|
,@one-arg-body)))))
|
||||||
|
|
||||||
|
(defgeneric init (client)
|
||||||
|
(:method ((client symbol))
|
||||||
|
(unless (fboundp client)
|
||||||
|
(error "client not funcallable"))
|
||||||
|
(init (fdefinition client)))
|
||||||
|
(:method ((client function))
|
||||||
|
(funcall client)))
|
||||||
|
|
||||||
|
(defgeneric stepper (client)
|
||||||
|
(:method ((client function))
|
||||||
|
(transducer-lambda
|
||||||
|
((acc a)
|
||||||
|
(declare (optimize (speed 3)))
|
||||||
|
(funcall client acc a))))
|
||||||
|
(:method ((client symbol))
|
||||||
|
(unless (fboundp client)
|
||||||
|
(error "client not funcallable"))
|
||||||
|
(init (fdefinition client))))
|
||||||
|
|
||||||
(defgeneric unwrap (client obj)
|
(defgeneric unwrap (client obj)
|
||||||
(:method (client obj) obj))
|
(:method (client obj) obj))
|
||||||
|
|
||||||
(defgeneric builder-for-input (seq)
|
(defgeneric builder-for-input (seq)
|
||||||
(:documentation
|
(:documentation
|
||||||
"Take a transducible sequence, return a builder and an init value for that builder.
|
"Take a transducible sequence, return a builder and an init value for that builder.
|
||||||
|
|
||||||
CONSTRAINT: SEQ should be copied, not modified"))
|
CONSTRAINT: SEQ should be copied, not modified"))
|
||||||
|
|
||||||
|
(declaim (inline exit-early))
|
||||||
(defun exit-early (acc)
|
(defun exit-early (acc)
|
||||||
(throw 'done acc))
|
(throw 'done acc))
|
||||||
|
(declaim (notinline exit-early))
|
||||||
|
|
||||||
(defun transduce (xf build seq)
|
(defun transduce (xf build seq)
|
||||||
(let* ((xf (etypecase xf
|
(let* ((xf (etypecase xf
|
||||||
@ -56,7 +73,16 @@ CONSTRAINT: SEQ should be copied, not modified"))
|
|||||||
transducer
|
transducer
|
||||||
(init build)))))))
|
(init build)))))))
|
||||||
|
|
||||||
(defun into (to xf from)
|
(defun into (to xf &optional (from nil from-p))
|
||||||
|
(if (not from-p)
|
||||||
|
(let ((from xf))
|
||||||
|
(data-lens.transducers:into to
|
||||||
|
(data-lens.transducers:mapping
|
||||||
|
(lambda (&rest args)
|
||||||
|
(if (null (cdr args))
|
||||||
|
(car args)
|
||||||
|
args)))
|
||||||
|
from))
|
||||||
(multiple-value-bind (builder init) (builder-for-input to)
|
(multiple-value-bind (builder init) (builder-for-input to)
|
||||||
(let* ((xf (etypecase xf
|
(let* ((xf (etypecase xf
|
||||||
(list (apply 'alexandria:compose xf))
|
(list (apply 'alexandria:compose xf))
|
||||||
@ -67,7 +93,7 @@ CONSTRAINT: SEQ should be copied, not modified"))
|
|||||||
(catch 'done
|
(catch 'done
|
||||||
(reduce-generic from
|
(reduce-generic from
|
||||||
transducer
|
transducer
|
||||||
init)))))))
|
init))))))))
|
||||||
|
|
||||||
(defmacro defdocumentation (name &body doc-specs)
|
(defmacro defdocumentation (name &body doc-specs)
|
||||||
name doc-specs
|
name doc-specs
|
||||||
|
|||||||
@ -23,7 +23,12 @@
|
|||||||
(lambda (rf)
|
(lambda (rf)
|
||||||
(transducer-lambda
|
(transducer-lambda
|
||||||
((acc next)
|
((acc next)
|
||||||
(funcall rf acc (call-function next)))
|
(restart-case
|
||||||
|
(funcall rf acc (call-function next))
|
||||||
|
(continue ()
|
||||||
|
:report (lambda (s)
|
||||||
|
(format s "skip this item"))
|
||||||
|
acc)))
|
||||||
((it) (funcall rf it))))))
|
((it) (funcall rf it))))))
|
||||||
|
|
||||||
(defun mv-mapping (function &rest args)
|
(defun mv-mapping (function &rest args)
|
||||||
|
|||||||
Reference in New Issue
Block a user