sunterlib/s48/sequences/genseqs.scm

200 lines
6.3 KiB
Scheme
Raw Normal View History

2003-02-11 19:23:30 -05:00
; Copyright (c) 2003 RT Happe <rthappe at web de>
; See the file COPYING distributed with the Scheme Untergrund Library
;;; generic sequence procedures -- no explicit dispatch on sequence type
;;;
;;; The code should work with the names of the elementary sequence
;;; operations bound to the umbrella procedures that dispatch on the
;;; sequence type, or to the specific procedures of a particular type,
;;;
;;; sequence->list
2003-02-12 16:48:40 -05:00
;;; sequence-fill!
2003-02-11 19:23:30 -05:00
;;; subsequence
2003-02-12 16:48:40 -05:00
;;; sequence-copy
;;; sequence-append
2003-02-13 19:47:58 -05:00
;;; sequence-map sequences-map
;;; sequence-for-each sequences-for-each
;;; sequence-fold sequences-fold
;;; sequence-fold-right sequence-fold-right
;;; sequence-any sequences-any
;;; sequence-every sequences-every
2003-02-11 19:23:30 -05:00
2003-02-14 21:48:52 -05:00
(define (id x) x)
(define (sequence->list s . opts)
(let-optionals opts ((start 0) (end (sequence-length s)))
(assert (<= 0 start end))
(let loop ((i end) (xs '()))
(if (= i start) xs
(loop (- i 1) (cons (sequence-ref s (- i 1)) xs))))))
2003-02-11 19:23:30 -05:00
;; unspecified return value as usual
2003-02-14 21:48:52 -05:00
(define (sequence-fill! s x . opts)
(let-optionals opts ((start 0) (end (sequence-length s)))
(assert (<= 0 start end))
2003-02-11 19:23:30 -05:00
(let loop ((i 0))
2003-02-14 21:48:52 -05:00
(if (< i end)
2003-02-11 19:23:30 -05:00
(begin
(sequence-set! s i x)
(loop (+ i 1)))))))
(define (subsequence s start end)
2003-02-14 21:48:52 -05:00
(assert (<= 0 start end))
2003-02-11 19:23:30 -05:00
(let* ((len (- end start))
(ss (make-another-sequence s len)))
(do ((i 0 (+ i 1)))
((= i len) ss)
(sequence-set! ss i (sequence-ref s (+ start i))))))
2003-02-12 16:48:40 -05:00
2003-02-14 21:48:52 -05:00
(define (sequence-copy s . opts)
(let-optionals opts ((start 0) (end (sequence-length s)))
(assert (<= 0 start end))
(subsequence s start end)))
2003-02-12 16:48:40 -05:00
2003-02-13 19:47:58 -05:00
(define (sequence-fold kons nil s . opts)
(let-optionals opts ((start 0)
(end (sequence-length s)))
2003-02-14 21:48:52 -05:00
(assert (<= 0 start end))
2003-02-13 19:47:58 -05:00
(let loop ((subtotal nil) (i start))
2003-02-12 16:48:40 -05:00
(if (= i end) subtotal
(loop (kons (sequence-ref s i) subtotal) (+ i 1))))))
2003-02-13 19:47:58 -05:00
(define (sequences-fold kons nil seq . seqs)
2003-02-12 16:48:40 -05:00
(if (null? seqs)
2003-02-13 19:47:58 -05:00
(sequence-fold kons nil seq)
2003-02-12 16:48:40 -05:00
(let* ((ss (cons seq seqs))
2003-02-13 19:47:58 -05:00
;; are we morally obliged to use FOLD here?
2003-02-12 16:48:40 -05:00
(end (apply min (map sequence-length ss))))
(let loop ((subtotal nil) (i 0))
(if (= i end) subtotal
(loop (apply kons (append! (map (lambda (s)
(sequence-ref s i))
ss)
(list subtotal)))
(+ i 1)))))))
2003-02-13 19:47:58 -05:00
(define (sequence-fold-right kons nil s . opts)
(let-optionals opts ((start 0)
(end (sequence-length s)))
2003-02-14 21:48:52 -05:00
(assert (<= 0 start end))
2003-02-13 19:47:58 -05:00
(let loop ((subtotal nil) (i end))
(if (= i start) subtotal
(loop (kons (sequence-ref s (- i 1)) subtotal) (- i 1))))))
(define (sequences-fold-right kons nil seq . seqs)
(if (null? seqs)
(sequence-fold-right kons nil seq)
(let* ((ss (cons seq seqs))
;; are we morally obliged to use FOLD here?
(end (apply min (map sequence-length ss))))
(let loop ((subtotal nil) (i (- end 1)))
(if (= i -1) subtotal
(loop (apply kons (append! (map (lambda (s)
(sequence-ref s i))
ss)
(list subtotal)))
(- i 1)))))))
2003-02-12 16:48:40 -05:00
(define (sequence-append . seqs)
(if (null? seqs) (vector)
(let* ((len (apply + (map sequence-length seqs)))
(res (make-another-sequence (car seqs) len)))
(let loop ((ss seqs) (start 0))
(if (null? ss) res
(let* ((s (car ss)) (end (sequence-length s)))
(do ((i 0 (+ i 1)))
((= i end) (loop (cdr ss) (+ start end)))
(sequence-set! res (+ start i)
(sequence-ref s i)))))))))
2003-02-13 19:47:58 -05:00
(define (sequence-for-each proc seq . opts)
(let-optionals opts ((start 0) (end (sequence-length seq)))
2003-02-14 21:48:52 -05:00
(assert (<= 0 start end))
2003-02-13 19:47:58 -05:00
(do ((i start (+ i 1)))
((= i end) (unspecific))
(proc (sequence-ref seq i)))))
(define (sequences-for-each proc seq . seqs)
2003-02-12 16:48:40 -05:00
(let* ((ss (cons seq seqs))
(end (apply min (map sequence-length ss))))
(do ((i 0 (+ i 1)))
((= i end) (unspecific))
(apply proc (map (lambda (s) (sequence-ref s i)) ss)))))
2003-02-13 19:47:58 -05:00
(define (sequence-map proc seq . opts)
(let-optionals opts ((start 0) (end (sequence-length seq)))
(assert (<= start end))
(let ((res (make-another-sequence seq end)))
(do ((i start (+ i 1)))
((= i end) res)
(sequence-set! res i (proc (sequence-ref seq i)))))))
(define (sequences-map proc seq . seqs)
2003-02-12 16:48:40 -05:00
(let* ((ss (cons seq seqs))
(end (apply min (map sequence-length ss)))
(res (make-another-sequence seq end)))
(do ((i 0 (+ i 1)))
((= i end) res)
(sequence-set! res i (apply proc (map (lambda (s) (sequence-ref s i))
ss))))))
2003-02-14 21:48:52 -05:00
(define (sequence-any foo? seq . opts)
2003-02-13 19:47:58 -05:00
(let-optionals opts ((start 0) (end (sequence-length seq)))
2003-02-14 21:48:52 -05:00
(assert (<= 0 start end))
2003-02-13 19:47:58 -05:00
(let loop ((i start))
(cond ((= i end) #f)
2003-02-14 21:48:52 -05:00
((foo? (sequence-ref seq i)) => id)
2003-02-13 19:47:58 -05:00
(else (loop (+ i 1)))))))
2003-02-12 16:48:40 -05:00
2003-02-13 19:47:58 -05:00
2003-02-14 21:48:52 -05:00
(define (sequences-any foo? . seqs)
2003-02-13 19:47:58 -05:00
(if (null? seqs) #f
2003-02-12 16:48:40 -05:00
(let ((end (apply min (map sequence-length seqs))))
(let loop ((i 0))
2003-02-13 19:47:58 -05:00
(cond ((= i end) #f)
2003-02-14 21:48:52 -05:00
((apply foo? (map (lambda (seq) (sequence-ref seq i))
2003-02-12 16:48:40 -05:00
seqs))
2003-02-14 21:48:52 -05:00
=> id)
2003-02-13 19:47:58 -05:00
(else (loop (+ i 1))))))))
2003-02-14 21:48:52 -05:00
(define (sequence-every foo? seq . opts)
2003-02-13 19:47:58 -05:00
(let-optionals opts ((start 0) (end (sequence-length seq)))
2003-02-14 21:48:52 -05:00
(assert (<= 0 start end))
(let loop ((i start) (res #t))
(cond ((= i end) res)
((foo? (sequence-ref seq i))
=> (lambda (r) (loop (+ i 1) r)))
2003-02-13 19:47:58 -05:00
(else #f)))))
2003-02-12 16:48:40 -05:00
2003-02-14 21:48:52 -05:00
(define (sequences-every foo? . seqs)
2003-02-12 16:48:40 -05:00
(if (null? seqs) #t
2003-02-13 19:47:58 -05:00
(let ((end (apply min (map sequence-length seqs))))
(let loop ((i 0))
(cond ((= i end) #t)
2003-02-14 21:48:52 -05:00
((apply foo? (map (lambda (seq) (sequence-ref seq i))
2003-02-12 16:48:40 -05:00
seqs))
(loop (+ i 1)))
(else #f))))))
2003-02-11 19:23:30 -05:00