aboutsummaryrefslogtreecommitdiff
path: root/module/hnh/util/table.scm
diff options
context:
space:
mode:
authorHugo Hörnquist <hugo@lysator.liu.se>2023-12-04 01:58:26 +0100
committerHugo Hörnquist <hugo@lysator.liu.se>2023-12-09 00:54:20 +0100
commitffd0a028aefd203b4a42ded1e5a592e1b4d92dd7 (patch)
tree7176aa23610558fde1c020ae0b096d2f43bc9dc7 /module/hnh/util/table.scm
parentCleanup datetime tests. (diff)
downloadcalp-ffd0a028aefd203b4a42ded1e5a592e1b4d92dd7.tar.gz
calp-ffd0a028aefd203b4a42ded1e5a592e1b4d92dd7.tar.xz
Complete rewrite of the lens system.
The old "lens" system was more of nested accessors. This rewrites them to be much better, at the cost of some extra up-front complexity. Beside the change in lenses, and all required adjustments, also adds lens creation to the define-type macro.
Diffstat (limited to 'module/hnh/util/table.scm')
-rw-r--r--module/hnh/util/table.scm25
1 files changed, 23 insertions, 2 deletions
diff --git a/module/hnh/util/table.scm b/module/hnh/util/table.scm
index 23ce6cd4..b318cf77 100644
--- a/module/hnh/util/table.scm
+++ b/module/hnh/util/table.scm
@@ -49,12 +49,33 @@
(or (tree-node? x)
(tree-terminal? x)))
+;;; A lens
+;;; This function (tree-focus)
+;;; returns a function (f),
+;;; which takes a function (g).
+;;;
+;;; g will be given the focused value in the tree, and should return
+;;; the new value for that node
+;;;
+;;; f takes such a modifier function, and returns a new tree identical
+;;; to the old tree, but with the value of that node changed
+(define (tree-focus tree k)
+ (lambda (op)
+ (cond ((tree-terminal? tree) ;; new node
+ (tree-node key: k value: (op 'not-a-value)))
+ ((eq? k (key tree)) ;; this node
+ (value tree (op (value truee))))
+ (else
+ (if (symbol<? k (key tree))
+ (lens-compose left* (tree-focus (left tree) k))
+ (lens-compose right* (tree-focus (right tree k))))))))
+
(define (tree-put tree k v)
(cond ((tree-terminal? tree) (tree-node key: k value: v))
((eq? k (key tree)) (value tree v))
(else
- (modify tree (if (symbol<? k (key tree)) left right)
- tree-put k v))))
+ (modify tree (if (symbol<? k (key tree)) left* right*)
+ (lambda (branch) (tree-put branch k v))))))
(define* (tree-get tree k optional: default)
(cond ((tree-terminal? tree) default)