feat: extensible lenses, add functionalize method for fset

This commit is contained in:
Edward Langley
2025-02-01 12:54:06 -08:00
parent 7618f95482
commit 742a155e91
2 changed files with 28 additions and 5 deletions

View File

@ -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))

View File

@ -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))))