(module list mzscheme
(require
(lib "etc.ss")
(lib "list.ss" "srfi" "1")
(file "base.ss")
)
(provide
(all-defined)
)
(define (list-delimit list delimiter)
(if (null? list)
null
(let loop ([rest list])
(if (null? (cdr rest))
(cons (car rest)
null)
(cons (car rest)
(cons delimiter
(loop (cdr rest))))))))
(define char-iota
(opt-lambda (count [start #\a])
(let loop ([i 0] [curr (char->integer start)])
(if (< i count)
(cons (integer->char curr)
(loop (add1 i) (add1 curr)))
null))))
(define (tree-map fn tree)
(let loop ([item tree])
(cond
[(list? item) (map loop item)]
[(pair? item) (cons (loop (car item)) (loop (cdr item)))]
[else (fn item)])))
(define (tree-for-each fn tree)
(let loop ([item tree])
(cond
[(list? item)
(for-each loop item)]
[(pair? item)
(loop (car item))
(loop (cdr item))]
[else
(fn item)])))
(define (assoc-value key alist)
(let ([kvp (assoc key alist)])
(if kvp
(cdr kvp)
(raise-exn exn:fail:unlib
(format "Key ~a not found in ~a.~n" key alist)))))
(define (assoc-value/default key alist default)
(let ([kvp (assoc key alist)])
(if kvp
(cdr kvp)
default)))
(define-syntax (alist-accessor stx)
(syntax-case stx ()
[(_ alist)
#'(lambda (key)
(assoc-value key alist))]))
(define-syntax (alist-accessor/default stx)
(syntax-case stx ()
[(_ alist default)
#'(lambda (key)
(assoc-value/default key alist default))]))
(define (alist-set key value alist)
(let* ([found #f]
[new-alist
(map
(lambda (kvp)
(if (equal? key (car kvp))
(begin
(set! found #t)
(cons (car kvp) value))
kvp))
alist)])
(if found
new-alist
(cons (cons key value) new-alist))))
(define-syntax (alist-mutator stx)
(syntax-case stx ()
[(_ alist)
#'(lambda (key val)
(set! alist (alist-set key val alist)))]))
(define-syntax (alist-mutator/append stx)
(syntax-case stx ()
[(_ alist)
#'(lambda (key val)
(let ([curr (assoc-value/default key alist null)])
(set! alist (alist-set key (append curr (list val)) alist))))]))
(define (alist-map proc alist)
(map
(lambda (kvp)
(if (pair? kvp)
(proc (car kvp) (cdr kvp))
(raise-exn
exn:fail:unlib
(format "alist-map: expected a pair: ~a" kvp))))
alist))
(define (alist-for-each proc alist)
(for-each
(lambda (kvp)
(if (pair? kvp)
(proc (car kvp) (cdr kvp))
(raise-exn
exn:fail:unlib
(format "alist-for-each: expected a pair: ~a" kvp))))
alist))
)