diff options
Diffstat (limited to 'module/hnh/util.scm')
-rw-r--r-- | module/hnh/util.scm | 55 |
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 ...)))) |