adding (srfi 41)

This commit is contained in:
Alex Shinn 2018-01-14 00:22:14 +09:00
parent 9e4eb03fb4
commit f8cc1402c2
5 changed files with 735 additions and 0 deletions

View file

@ -1187,6 +1187,7 @@ snow-fort):
\item{\hyperlink["http://srfi.schemers.org/srfi-33/srfi-33.html"]{(srfi 33) - bitwise operators}}
\item{\hyperlink["http://srfi.schemers.org/srfi-38/srfi-38.html"]{(srfi 38) - read/write shared structures}}
\item{\hyperlink["http://srfi.schemers.org/srfi-39/srfi-39.html"]{(srfi 39) - parameter objects}}
\item{\hyperlink["http://srfi.schemers.org/srfi-41/srfi-41.html"]{(srfi 41) - streams}}
\item{\hyperlink["http://srfi.schemers.org/srfi-46/srfi-46.html"]{(srfi 46) - basic syntax-rules extensions}}
\item{\hyperlink["http://srfi.schemers.org/srfi-55/srfi-55.html"]{(srfi 55) - require-extension}}
\item{\hyperlink["http://srfi.schemers.org/srfi-62/srfi-62.html"]{(srfi 62) - s-expression comments}}

359
lib/srfi/41.scm Normal file
View file

@ -0,0 +1,359 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; primitive layer adapted from SRFI 41 reference impl
;; TODO: rewrite this in terms or R7RS lazy primitives
(define-record-type Stream
(make-stream box)
stream?
(box stream-promise stream-promise!))
(define-record-type Stream-Pare
(make-stream-pare kar kdr)
stream-pare?
(kar stream-kar)
(kdr stream-kdr))
(define-syntax stream-lazy
(syntax-rules ()
((lazy expr)
(make-stream (cons 'lazy (lambda () expr))))))
(define (stream-eager expr)
(make-stream (cons 'eager expr)))
(define-syntax stream-delay
(syntax-rules ()
((stream-delay expr)
(stream-lazy (stream-eager expr)))))
(define (stream-force promise)
(let ((content (stream-promise promise)))
(case (car content)
((eager) (cdr content))
((lazy) (let* ((promise* ((cdr content)))
(content (stream-promise promise)))
(if (not (eqv? (car content) 'eager))
(begin (set-car! content (car (stream-promise promise*)))
(set-cdr! content (cdr (stream-promise promise*)))
(stream-promise! promise* content)))
(stream-force promise))))))
(define stream-null (stream-delay (cons 'stream 'null)))
(define (stream-pair? obj)
(and (stream? obj) (stream-pare? (stream-force obj))))
(define (stream-null? obj)
(and (stream? obj)
(eqv? (stream-force obj)
(stream-force stream-null))))
(define-syntax stream-cons
(syntax-rules ()
((stream-cons obj strm)
(stream-delay (make-stream-pare (stream-delay obj) (stream-lazy strm))))))
(define (stream-car strm)
(cond ((not (stream? strm)) (error 'stream-car "non-stream"))
((stream-null? strm) (error 'stream-car "null stream"))
(else (stream-force (stream-kar (stream-force strm))))))
(define (stream-cdr strm)
(cond ((not (stream? strm)) (error 'stream-cdr "non-stream"))
((stream-null? strm) (error 'stream-cdr "null stream"))
(else (stream-kdr (stream-force strm)))))
(define-syntax stream-lambda
(syntax-rules ()
((stream-lambda formals body0 body1 ...)
(lambda formals (stream-lazy (let () body0 body1 ...))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; derived
(define-syntax assert
(syntax-rules ()
((assert expr ...)
(begin (unless expr (error "assertion failed" 'expr)) ...))))
(define-syntax define-stream
(syntax-rules ()
((define-stream (name . args) e0 e1 ...)
(define name
(stream-lambda args e0 e1 ...)))))
(define-syntax stream-let
(syntax-rules ()
((stream-let lp ((name val) ...) e0 e1 ...)
((letrec ((lp (stream-lambda (name ...) e0 e1 ...))) lp)
val ...))))
(define-syntax stream
(syntax-rules ()
((stream) stream-null)
((stream x y ...) (stream-cons x (stream y ...)))))
(define (list->stream ls)
(assert (list? ls))
(let lp ((ls (reverse ls)) (res stream-null))
(if (null? ls)
res
(lp (cdr ls) (stream-cons (car ls) res)))))
(define (port->stream in)
(assert (input-port? in))
(let lp ()
(let ((ch (read-char in)))
(if (eof-object? ch)
stream-null
(stream-cons ch (lp))))))
(define (stream->list x . o)
(let ((n (if (pair? o) x +inf.0)))
(assert (not (negative? n)))
(let lp ((i 0)
(strm (if (pair? o) (car o) x))
(res '()))
(if (or (>= i n) (stream-null? strm))
(reverse res)
(lp (+ i 1)
(stream-cdr strm)
(cons (stream-car strm) res))))))
(define (stream-concat strms)
(assert (stream? strms))
(if (stream-null? strms)
stream-null
(let lp ((strm (stream-car strms))
(strms (stream-cdr strms)))
(assert (stream? strm))
(cond
((stream-null? strm)
(if (stream-null? strms)
stream-null
(lp (stream-car strms) (stream-cdr strms))))
(else
(stream-cons (stream-car strm)
(lp (stream-cdr strm) strms)))))))
(define (stream-append . strms)
(stream-concat (list->stream strms)))
(define (stream-from n . o)
(let ((step (if (pair? o) (car o) 1)))
(assert (number? n) (number? step))
(let lp ((n n))
(stream-cons n (lp (+ n step))))))
(define (stream-range first past . o)
(let ((step (if (pair? o) (car o) (if (< first past) 1 -1))))
(assert (number? first) (number? past) (number? step))
(if (positive? step)
(stream-let lp ((n first))
(if (< n past)
(stream-cons n (lp (+ n step)))
stream-null))
(stream-let lp ((n first))
(if (> n past)
(stream-cons n (lp (+ n step)))
stream-null)))))
(define (stream-constant . o)
(let lp ((ls o))
(if (null? ls)
(lp o)
(stream-cons (car ls) (lp (cdr ls))))))
(define (stream-ref strm k)
(assert (stream? strm) (integer? k) (not (negative? k)))
(if (positive? k)
(stream-ref (stream-cdr strm) (- k 1))
(stream-car strm)))
(define (stream-length strm)
(assert (stream? strm))
(let lp ((strm strm) (len 0))
(if (stream-null? strm)
len
(lp (stream-cdr strm) (+ len 1)))))
(define (stream-drop k strm)
(assert (integer? k) (not (negative? k)) (stream? strm))
(stream-let drop ((k k) (strm strm))
(if (or (zero? k) (stream-null? strm))
strm
(drop (- k 1) (stream-cdr strm)))))
(define (stream-drop-while pred? strm)
(assert (procedure? pred?) (stream? strm))
(stream-let drop-while ((strm strm))
(if (or (stream-null? strm) (not (pred? (stream-car strm))))
strm
(drop-while (stream-cdr strm)))))
(define (stream-filter pred? strm)
(assert (procedure? pred?) (stream? strm))
(stream-let filter ((strm strm))
(cond ((stream-null? strm) stream-null)
((pred? (stream-car strm))
(stream-cons (stream-car strm) (filter (stream-cdr strm))))
(else not (filter (stream-cdr strm))))))
(define (stream-for-each proc strm)
(assert (procedure? proc) (stream? strm))
(when (stream-pair? strm)
(proc (stream-car strm))
(stream-for-each proc (stream-cdr strm))))
(define (stream-fold kons knil strm)
(assert (procedure? kons) (stream? strm))
(let fold ((acc knil) (strm strm))
(if (stream-null? strm)
acc
(fold (kons (stream-car strm) acc) (stream-cdr strm)))))
(define (stream-scan proc base strm)
(assert (procedure? proc) (stream? strm))
(stream-let scan ((acc base) (strm strm))
(if (stream-null? strm)
(stream acc)
(stream-cons acc
(scan (proc acc (stream-car strm))
(stream-cdr strm))))))
(define (stream-map proc strm . o)
(assert (procedure? proc) (stream? strm))
(if (pair? o)
(stream-let lp ((strms (cons strm o)))
(if (any stream-null? strms)
stream-null
(stream-cons (apply proc (map stream-car strms))
(lp (map stream-cdr strms)))))
(stream-let lp ((strm strm))
(if (stream-null? strm)
stream-null
(stream-cons (proc (stream-car strm))
(lp (stream-cdr strm)))))))
(define (stream-iterate proc base)
(assert (procedure? proc))
(stream-let iterate ((base base))
(stream-cons base (iterate (proc base)))))
(define (stream-take k strm)
(assert (integer? k) (not (negative? k)) (stream? strm))
(stream-let take ((k k) (strm strm))
(if (and (positive? k) (stream-pair? strm))
(stream-cons (stream-car strm) (take (- k 1) (stream-cdr strm)))
stream-null)))
(define (stream-take-while pred strm)
(assert (procedure? pred) (stream? strm))
(stream-let take-while ((strm strm))
(if (and (stream-pair? strm) (pred (stream-car strm)))
(stream-cons (stream-car strm) (take-while (stream-cdr strm)))
stream-null)))
(define-syntax stream-of
(syntax-rules ()
((stream-of expr . clauses)
(stream-of/aux expr stream-null . clauses))))
(define-syntax stream-of/aux
(syntax-rules (in is)
((stream-of/aux expr tail)
(stream-cons expr tail))
((stream-of/aux expr tail (var in s) . rest)
(stream-let lp ((strm s))
(if (stream-null? strm)
tail
(let ((var (stream-car strm)))
(stream-of/aux expr (lp (stream-cdr strm)) . rest)))))
((stream-of/aux expr tail (var is e) . rest)
(let ((var e))
(stream-of/aux expr tail . rest)))
((stream-of/aux expr tail pred . rest)
(if pred (stream-of/aux expr tail . rest) tail))))
(define (stream-reverse strm)
(list->stream (reverse (stream->list strm))))
(define (stream-unfold mapper pred gen base)
(assert (procedure? mapper) (procedure? pred) (procedure? gen))
(stream-let unfold ((base base))
(if (pred base)
(stream-cons (mapper base) (unfold (gen base)))
stream-null)))
(define (stream-unfolds proc seed)
(assert (procedure? proc))
(let ((strm (stream-let lp ((seed seed))
(call-with-values
(lambda () (proc seed))
(lambda ls
(stream-cons (cdr ls)
(lp (car ls))))))))
(apply values
(map (lambda (i)
(stream-let lp ((strm strm))
(let ((x (list-ref (stream-car strm) i)))
(cond
((null? x) stream-null)
((pair? x) (stream-cons (car x) (lp (stream-cdr strm))))
(else (lp (stream-cdr strm)))))))
(iota (length (stream-car strm)))))))
(define (stream-zip strm . o)
(assert (stream? strm) (every stream? o))
(stream-let lp ((strms (cons strm o)))
(if (every stream-pair? strms)
(stream-cons (map stream-car strms)
(lp (map stream-cdr strms)))
stream-null)))
(define-syntax stream-match
(syntax-rules ()
((stream-match expr clause ...)
(let ((strm expr))
(assert (stream? strm))
(stream-match-next strm clause ...)))))
(define-syntax stream-match-next
(syntax-rules ()
((stream-match-next strm)
(error "no pattern matched"))
((stream-match-next strm clause . clauses)
(let ((fail (lambda () (stream-match-next strm . clauses))))
(stream-match-one strm clause (fail))))))
(define-syntax stream-match-one
(syntax-rules (_)
((stream-match-one strm (() . body) fail)
(if (stream-null? strm)
(stream-match-body fail . body)
fail))
((stream-match-one strm (_ . body) fail)
(stream-match-body fail . body))
((stream-match-one strm ((a . b) . body) fail)
(if (stream-pair? strm)
(stream-match-one
(stream-car strm)
(a
(stream-match-one (stream-cdr strm) (b . body) fail))
fail)
fail))
((stream-match-one strm (a . body) fail)
(let ((a strm))
(stream-match-body fail . body)))))
(define-syntax stream-match-body
(syntax-rules ()
((stream-match-body fail fender expr)
(if fender expr fail))
((stream-match-body fail expr)
expr)))
;; Local variables:
;; eval: (put 'stream-let 'scheme-indent-function 2)
;; End:

14
lib/srfi/41.sld Normal file
View file

@ -0,0 +1,14 @@
(define-library (srfi 41)
(import (scheme base) (srfi 1))
(export
stream-null stream-cons stream? stream-null? stream-pair?
stream-car stream-cdr stream-lambda)
(export
define-stream list->stream port->stream stream stream->list
stream-append stream-concat stream-constant stream-drop
stream-drop-while stream-filter stream-fold stream-for-each stream-from
stream-iterate stream-length stream-let stream-map stream-match _
stream-of stream-range stream-ref stream-reverse stream-scan stream-take
stream-take-while stream-unfold stream-unfolds stream-zip)
(include "41.scm"))

359
lib/srfi/41/test.sld Normal file
View file

@ -0,0 +1,359 @@
;; Adapted for R7RS from original SRFI 41 r5rs.ss.
;; Copyright (C) 2007 by Philip L. Bewig of Saint Louis, Missouri,
;; USA. All rights reserved. Permission is hereby granted, free of
;; charge, to any person obtaining a copy of this software and
;; associated documentation files (the "Software"), to deal in the
;; Software without restriction, including without limitation the
;; rights to use, copy, modify, merge, publish, distribute,
;; sublicense, and/or sell copies of the Software, and to permit
;; persons to whom the Software is furnished to do so, subject to the
;; following conditions: The above copyright notice and this
;; permission notice shall be included in all copies or substantial
;; portions of the Software. THE SOFTWARE IS PROVIDED "AS IS",
;; WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
;; LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
;; PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
;; OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
;; OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
;; OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; unit tests
(define-library (srfi 41 test)
(import (scheme base) (srfi 41) (chibi test))
(export run-tests)
(begin
(define (add1 n) (+ n 1))
(define strm123 (stream 1 2 3))
(define (lsec proc . args)
(lambda x (apply proc (append args x))))
(define (rsec proc . args)
(lambda x (apply proc (reverse (append (reverse args) (reverse x))))))
(define nats
(stream-cons 0 (stream-map add1 nats)))
;; executing (run-tests) should produce no output
(define (run-tests)
(test-begin "srfi-41: streams")
;; stream-null
(test #t (stream? stream-null))
(test #t (stream-null? stream-null))
(test #f (stream-pair? stream-null))
;; stream-cons
(test #t (stream? (stream-cons 1 stream-null)))
(test #f (stream-null? (stream-cons 1 stream-null)))
(test #t (stream-pair? (stream-cons 1 stream-null)))
;; stream?
(test #t (stream? stream-null))
(test #t (stream? (stream-cons 1 stream-null)))
(test #f (stream? "four"))
;; stream-null?
(test #t (stream-null? stream-null))
(test #f (stream-null? (stream-cons 1 stream-null)))
(test #f (stream-null? "four"))
;; stream-pair?
(test #f (stream-pair? stream-null))
(test #t (stream-pair? (stream-cons 1 stream-null)))
(test #f (stream-pair? "four"))
;; stream-car
(test-error (stream-car "four")) ; "stream-car: non-stream"
(test-error (stream-car stream-null)) ; "stream-car: null stream"
(test 1 (stream-car strm123))
;; stream-cdr
(test-error (stream-cdr "four")) ; "stream-cdr: non-stream"
(test-error (stream-cdr stream-null)) ; "stream-cdr: null stream"
(test 2 (stream-car (stream-cdr strm123)))
;; stream-lambda
(test
'(2 4 6)
(stream->list
(letrec ((double
(stream-lambda (strm)
(if (stream-null? strm)
stream-null
(stream-cons
(* 2 (stream-car strm))
(double (stream-cdr strm)))))))
(double strm123))))
;; define-stream
(test
'(2 4 6)
(stream->list
(let ()
(define-stream (double strm)
(if (stream-null? strm)
stream-null
(stream-cons
(* 2 (stream-car strm))
(double (stream-cdr strm)))))
(double strm123))))
;; list->stream
(test-error (list->stream "four")) ; "list->stream: non-list argument"
(test '() (stream->list (list->stream '())))
(test '(1 2 3) (stream->list (list->stream '(1 2 3))))
;; port->stream
(let* ((p (open-input-string "; Copyright 2007"))
(s (port->stream p)))
(test-error (port->stream "four"))
(test "; Copyright" (list->string (stream->list 11 s)) )
(close-input-port p))
;; stream
(test '() (stream->list (stream)))
(test '(1) (stream->list (stream 1)))
(test '(1 2 3) (stream->list (stream 1 2 3)))
;; stream->list
(test-error (stream->list '())) ; "stream->list: non-stream argument"
(test-error (stream->list "four" strm123)) ; "stream->list: non-integer count"
(test-error (stream->list -1 strm123)) ; "stream->list: negative count"
(test '() (stream->list (stream)))
(test '(1 2 3) (stream->list strm123))
(test '(1 2 3) (stream->list 5 strm123))
(test '(1 2 3) (stream->list 3 (stream-from 1)))
;; stream-append
(test-error (stream-append "four")) ; "stream-append: non-stream argument"
(test '(1 2 3) (stream->list (stream-append strm123)))
(test '(1 2 3 1 2 3) (stream->list (stream-append strm123 strm123)))
(test '(1 2 3 1 2 3 1 2 3)
(stream->list (stream-append strm123 strm123 strm123)))
(test '(1 2 3) (stream->list (stream-append strm123 stream-null)))
(test '(1 2 3) (stream->list (stream-append stream-null strm123)))
;; stream-concat
(test-error (stream-concat "four")) ; "stream-concat: non-stream argument"
(test '(1 2 3) (stream->list (stream-concat (stream strm123))))
(test '(1 2 3 1 2 3)
(stream->list (stream-concat (stream strm123 strm123))))
;; stream-constant
(test 1 (stream-ref (stream-constant 1) 100))
(test 1 (stream-ref (stream-constant 1 2) 100))
(test 1 (stream-ref (stream-constant 1 2 3) 3))
;; stream-drop
(test-error (stream-drop "four" strm123)) ; "stream-drop: non-integer argument"
(test-error (stream-drop -1 strm123)) ; "stream-drop: negative argument"
(test-error (stream-drop 2 "four")) ; "stream-drop: non-stream argument"
(test '() (stream->list (stream-drop 0 stream-null)))
(test '(1 2 3) (stream->list (stream-drop 0 strm123)))
(test '(2 3) (stream->list (stream-drop 1 strm123)))
(test '() (stream->list (stream-drop 5 strm123)))
;; stream-drop-while
(test-error ; "stream-drop-while: non-procedural argument"
(stream-drop-while "four" strm123))
(test-error ; "stream-drop-while: non-stream argument"
(stream-drop-while odd? "four"))
(test '() (stream->list (stream-drop-while odd? stream-null)))
(test '(2 3) (stream->list (stream-drop-while odd? strm123)))
(test '(1 2 3) (stream->list (stream-drop-while even? strm123)))
(test '() (stream->list (stream-drop-while positive? strm123)))
(test '(1 2 3) (stream->list (stream-drop-while negative? strm123)))
;; stream-filter
(test-error ; "stream-filter: non-procedural argument"
(stream-filter "four" strm123))
(test-error (stream-filter odd? '())) ; "stream-filter: non-stream argument"
(test #t (stream-null? (stream-filter odd? (stream))))
(test '(1 3) (stream->list (stream-filter odd? strm123)))
(test '(2) (stream->list (stream-filter even? strm123)))
(test '(1 2 3) (stream->list (stream-filter positive? strm123)))
(test '() (stream->list (stream-filter negative? strm123)))
(let loop ((n 10))
(test #t (odd? (stream-ref (stream-filter odd? (stream-from 0)) n)))
(if (positive? n) (loop (- n 1))))
(let loop ((n 10))
(test #f (even? (stream-ref (stream-filter odd? (stream-from 0)) n)))
(if (positive? n) (loop (- n 1))))
;; stream-fold
(test-error ; "stream-fold: non-procedural argument"
(stream-fold "four" 0 strm123))
(test-error (stream-fold + 0 '())) ; "stream-fold: non-stream argument"
(test 6 (stream-fold + 0 strm123))
;; stream-for-each
(test-error ; "stream-for-each: non-procedural argument"
(stream-for-each "four" strm123))
(test-error ; "stream-for-each: no stream arguments"
(stream-for-each +))
(test-error ; "stream-for-each: non-stream argument"
(stream-for-each + "four"))
(test 6
(let ((sum 0))
(stream-for-each (lambda (x) (set! sum (+ sum x))) strm123)
sum))
;; stream-from
(test-error (stream-from "four")) ; "stream-from: non-numeric starting number"
(test-error (stream-from 1 "four")) ; "stream-from: non-numeric step size"
(test 100 (stream-ref (stream-from 0) 100))
(test 201 (stream-ref (stream-from 1 2) 100))
(test -100 (stream-ref (stream-from 0 -1) 100))
;; stream-iterate
(test-error (stream-iterate "four" 0)) ; "stream-iterate: non-procedural argument"
(test '(1 2 3) (stream->list 3 (stream-iterate (lsec + 1) 1)))
;; stream-length
(test-error (stream-length "four")) ; "stream-length: non-stream argument"
(test 0 (stream-length (stream)))
(test 3 (stream-length strm123))
;; stream-let
(test '(2 4 6)
(stream->list
(stream-let loop ((strm strm123))
(if (stream-null? strm)
stream-null
(stream-cons
(* 2 (stream-car strm))
(loop (stream-cdr strm)))))))
;; stream-map
(test-error (stream-map "four" strm123)) ; "stream-map: non-procedural argument"
(test-error (stream-map odd?)) ; "stream-map: no stream arguments"
(test-error (stream-map odd? "four")) ; "stream-map: non-stream argument"
(test '(-1 -2 -3) (stream->list (stream-map - strm123)))
(test '(2 4 6) (stream->list (stream-map + strm123 strm123)))
(test '(2 4 6) (stream->list (stream-map + strm123 (stream-from 1))))
(test '(2 4 6) (stream->list (stream-map + (stream-from 1) strm123)))
(test '(3 6 9) (stream->list (stream-map + strm123 strm123 strm123)))
;; stream-match
(test-error (stream-match '(1 2 3) (_ 'ok))) ; "stream-match: non-stream argument"
(test-error (stream-match strm123 (() 42))) ; "stream-match: pattern failure"
(test 'ok (stream-match stream-null (() 'ok)))
(test 'ok (stream-match strm123 (() 'no) (else 'ok)))
(test 1 (stream-match (stream 1) (() 'no) ((a) a)))
(test 'ok (stream-match (stream 1) (() 'no) ((_) 'ok)))
(test '(1 2 3) (stream-match strm123 ((a b c) (list a b c))))
(test 1 (stream-match strm123 ((a . _) a)))
(test '(1 2) (stream-match strm123 ((a b . _) (list a b))))
(test '(1 2 3)
(stream-match strm123 ((a b . c) (list a b (stream-car c)))))
(test '(1 2 3) (stream-match strm123 (s (stream->list s))))
(test 'ok (stream-match strm123 ((a . _) (= a 1) 'ok)))
(test 'no (stream-match strm123 ((a . _) (= a 2) 'yes) (_ 'no)))
(test 'no (stream-match strm123 ((a b c) (= a b) 'yes) (_ 'no)))
(test 'yes (stream-match (stream 1 1 2) ((a b c) (= a b) 'yes) (_ 'no)))
;; stream-of
(test '(7 15 31)
(stream->list
(stream-of (+ y 6)
(x in (stream-range 1 6))
(odd? x)
(y is (* x x)))))
(test '(1 2 3 4 2 4 6 8 3 6 9 12)
(stream->list
(stream-of (* x y)
(x in (stream-range 1 4))
(y in (stream-range 1 5)))))
(test 1 (stream-car (stream-of 1)))
;; stream-range
(test-error (stream-range "four" 0)) ; "stream-range: non-numeric starting number"
(test-error (stream-range 0 "four")) ; "stream-range: non-numeric ending number"
(test-error (stream-range 1 2 "three")) ; "stream-range: non-numeric step size"
(test '(0 1 2 3 4) (stream->list (stream-range 0 5)))
(test '(5 4 3 2 1) (stream->list (stream-range 5 0)))
(test '(0 2 4) (stream->list (stream-range 0 5 2)))
(test '(5 3 1) (stream->list (stream-range 5 0 -2)))
(test '() (stream->list (stream-range 0 1 -1)))
;; stream-ref
(test-error (stream-ref '() 4)) ; "stream-ref: non-stream argument"
(test-error (stream-ref nats 3.5)) ; "stream-ref: non-integer argument"
(test-error (stream-ref nats -3)) ; "stream-ref: negative argument"
(test-error (stream-ref strm123 5)) ; "stream-ref: beyond end of stream"
(test 1 (stream-ref strm123 0))
(test 2 (stream-ref strm123 1))
(test 3 (stream-ref strm123 2))
;; stream-reverse
(test-error (stream-reverse '())) ; "stream-reverse: non-stream argument"
(test '() (stream->list (stream-reverse (stream))))
(test '(3 2 1) (stream->list (stream-reverse strm123)))
;; stream-scan
(test-error ; "stream-scan: non-procedural argument"
(stream-scan "four" 0 strm123))
(test-error (stream-scan + 0 '())) ; "stream-scan: non-stream argument"
(test '(0 1 3 6) (stream->list (stream-scan + 0 strm123)))
;; stream-take
(test-error (stream-take 5 "four")) ; "stream-take: non-stream argument"
(test-error (stream-take "four" strm123)) ; "stream-take: non-integer argument"
(test-error (stream-take -4 strm123)) ; "stream-take: negative argument"
(test '() (stream->list (stream-take 5 stream-null)))
(test '() (stream->list (stream-take 0 stream-null)))
(test '() (stream->list (stream-take 0 strm123)))
(test '(1 2) (stream->list (stream-take 2 strm123)))
(test '(1 2 3) (stream->list (stream-take 3 strm123)))
(test '(1 2 3) (stream->list (stream-take 5 strm123)))
;; stream-take-while
(test-error ; "stream-take-while: non-stream argument"
(stream-take-while odd? "four"))
(test-error ; "stream-take-while: non-procedural argument"
(stream-take-while "four" strm123))
(test '(1) (stream->list (stream-take-while odd? strm123)))
(test '() (stream->list (stream-take-while even? strm123)))
(test '(1 2 3) (stream->list (stream-take-while positive? strm123)))
(test '() (stream->list (stream-take-while negative? strm123)))
;; stream-unfold
(test-error ; "stream-unfold: non-procedural mapper"
(stream-unfold "four" odd? + 0))
(test-error ; "stream-unfold: non-procedural pred?"
(stream-unfold + "four" + 0))
(test-error ; "stream-unfold: non-procedural generator"
(stream-unfold + odd? "four" 0))
(test '(0 1 4 9 16 25 36 49 64 81)
(stream->list (stream-unfold (rsec expt 2) (rsec < 10) (rsec + 1) 0)))
;; stream-unfolds
(test
'(0 1 2 3 4)
(stream->list
(stream-unfolds
(lambda (x)
(let ((n (car x)) (s (cdr x)))
(if (zero? n)
(values 'dummy '())
(values
(cons (- n 1) (stream-cdr s))
(list (stream-car s))))))
(cons 5 (stream-from 0)))))
;; stream-zip
(test-error (stream-zip)) ; "stream-zip: no stream arguments"
(test-error (stream-zip "four")) ; "stream-zip: non-stream argument"
(test-error (stream-zip strm123 "four")) ; "stream-zip: non-stream argument"
(test '() (stream->list (stream-zip strm123 stream-null)))
(test '((1) (2) (3)) (stream->list (stream-zip strm123)))
(test '((1 1) (2 2) (3 3)) (stream->list (stream-zip strm123 strm123)))
(test '((1 1) (2 2) (3 3))
(stream->list (stream-zip strm123 (stream-from 1))))
(test '((1 1 1) (2 2 2) (3 3 3))
(stream->list (stream-zip strm123 strm123 strm123)))
(test-end))))

View file

@ -9,6 +9,7 @@
(rename (srfi 26 test) (run-tests run-srfi-26-tests))
(rename (srfi 27 test) (run-tests run-srfi-27-tests))
(rename (srfi 38 test) (run-tests run-srfi-38-tests))
(rename (srfi 41 test) (run-tests run-srfi-41-tests))
(rename (srfi 69 test) (run-tests run-srfi-69-tests))
(rename (srfi 95 test) (run-tests run-srfi-95-tests))
(rename (srfi 99 test) (run-tests run-srfi-99-tests))
@ -62,6 +63,7 @@
(run-srfi-26-tests)
(run-srfi-27-tests)
(run-srfi-38-tests)
(run-srfi-41-tests)
(run-srfi-69-tests)
(run-srfi-95-tests)
(run-srfi-99-tests)