aboutsummaryrefslogtreecommitdiff
path: root/module/hnh/util.scm
diff options
context:
space:
mode:
Diffstat (limited to 'module/hnh/util.scm')
-rw-r--r--module/hnh/util.scm55
1 files changed, 47 insertions, 8 deletions
diff --git a/module/hnh/util.scm b/module/hnh/util.scm
index d2c0dd5f..c88a029e 100644
--- a/module/hnh/util.scm
+++ b/module/hnh/util.scm
@@ -17,6 +17,7 @@
find-extreme find-min find-max
filter-sorted
!=
+ init+last
take-to
string-take-to
string-first
@@ -55,6 +56,12 @@
assq-ref-all
assv-ref-all
+ uniqx
+ uniq
+ univ
+ uniqv
+ unique
+
vector-last
->string
@@ -64,6 +71,10 @@
:replace (set! define-syntax
when unless))
+(cond-expand
+ (guile-3 (use-modules ((ice-9 copy-tree) :select (copy-tree))))
+ (else))
+
((@ (guile) define-syntax) define-syntax
(syntax-rules ()
((_ (name args ...) body ...)
@@ -112,6 +123,9 @@
((for (<var> <vars> ...) in <collection> b1 body ...)
(map ((@ (ice-9 match) match-lambda) [(<var> <vars> ...) b1 body ...])
<collection>))
+ ((for (<var> <vars> ... . <tail>) in <collection> b1 body ...)
+ (map ((@ (ice-9 match) match-lambda) [(<var> <vars> ... . <tail>) b1 body ...])
+ <collection>))
((for <var> in <collection> b1 body ...)
(map (lambda (<var>) b1 body ...)
<collection>))))
@@ -137,9 +151,12 @@
+;; TODO this is called flip in Haskell land
(define (swap f)
(lambda args (apply f (reverse args))))
-
+;; Swap would be
+;; (define (swap p)
+;; (xcons (car p) (cdr p)))
;; Allow set to work on multiple values at once,
;; similar to Common Lisp's @var{setf}
@@ -240,6 +257,12 @@
;; (define (!= a b) (not (= a b)))
(define != (negate =))
+
+(define (init+last l)
+ (let ((last rest (car+cdr (reverse l))))
+ (values (reverse rest) last)))
+
+
(define (take-to lst i)
"Like @var{take}, but might lists shorter than length."
(if (> i (length lst))
@@ -307,7 +330,8 @@
(define (kvlist->assq kvlist)
(map (lambda (pair)
- (cons (keyword->symbol (car pair)) (cdr pair)))
+ (cons (keyword->symbol (car pair))
+ (cadr pair)))
(group kvlist 2)))
(define* (assq-limit alist optional: (number 1))
@@ -320,8 +344,7 @@
(for value in lst
(let ((key (proc value)))
(hash-set! h key (cons value (hash-ref h key '())))))
- ;; NOTE changing this list to cons allows the output to work with assq-merge.
- (hash-map->list list h)))
+ (hash-map->list cons h)))
;; (split-by '(0 1 2 3 4 2 5 6) 2)
;; ⇒ ((0 1) (3 4) (5 6))
@@ -383,7 +406,7 @@
(reverse (cons (map list last) rest ))))))
;; Given an arbitary tree, do a pre-order traversal, appending all strings.
-;; non-strings allso allowed, converted to strings and also appended.
+;; non-strings also allowed, converted to strings and also appended.
(define (string-flatten tree)
(cond [(string? tree) tree]
[(list? tree) (string-concatenate (map string-flatten tree))]
@@ -506,6 +529,19 @@
(define (assv-ref-all alist key) (ass%-ref-all alist key eqv?))
+(define (uniqx = lst)
+ (cond ((null? lst) lst)
+ ((null? (cdr lst)) lst)
+ ((and (pair? lst)
+ (= (car lst) (cadr lst)))
+ (uniqx = (cons (car lst) (cddr lst))))
+ (else (cons (car lst)
+ (uniqx = (cdr lst))))))
+
+(define (uniq lst) (uniqx eq? lst))
+(define (univ lst) (uniqx eqv? lst))
+(define (unique lst) (uniqx equal? lst))
+
(define (vector-last v)
@@ -517,9 +553,12 @@
(define-syntax catch*
- (syntax-rules ()
+ (syntax-rules (pre-unwind)
+ ((_ thunk ((pre-unwind key) handler))
+ (with-throw-handler (quote key) thunk handler))
((_ thunk (key handler))
(catch (quote key) thunk handler))
- ((_ thunk (key handler) rest ...)
- (catch* (lambda () (catch (quote key) thunk handler))
+
+ ((_ thunk pair rest ...)
+ (catch* (lambda () (catch* thunk pair))
rest ...))))