;; Reconciling srfi-41 and ice-9 streams.
(use-modules (srfi srfi-41))
;; srfi-41 does not have ice-9 streams make-stream.
(define (make-stream proc init)
(stream-let loop ((init (proc init)))
(if (pair? init)
(stream-cons (car init) (loop (proc (cdr init))))
stream-null)))
;; ice-9 streams does not have srfi-41 stream-take (not needed here).
(define (stream-take n stream)
(make-stream (lambda (state)
(let ((s (car state))
(n (cdr state)))
(unless (or (stream-null? s)
(<= n 0))
(cons* (stream-car s) (stream-cdr s) (- n 1)))))
(cons stream n)))
;; Write cycle and repeat in terms of make-stream.
(define (stream-cycle head)
(make-stream (lambda (rest)
(if (null? rest)
head
rest))
head))
(define* (stream-repeat item #:optional (count -1))
;; Negative count is infinite.
(make-stream (lambda (n)
(unless (zero? n)
(cons item (- n 1))))
count))
(display (stream->list (stream-take 10 (stream-cycle '(1 2 3)))))
(newline)
(display (stream->list (stream-take 10 (stream-repeat #\X))))
(newline)
(display (stream->list (stream-repeat #\Y 5)))
(newline)
;; With stream-take there isn't much reason to allow stream-repeat
;; to accept a count; write in terms of stream-cycle.
(define (stream-repeat item)
(stream-cycle (list item)))
(display (stream->list (stream-take 10 (stream-cycle '(1 2 3)))))
(newline)
(display (stream->list (stream-take 10 (stream-repeat #\X))))
(newline)
(display (stream->list (stream-take 5 (stream-repeat #\Y))))
(newline)
;; Write stream-cycle in terms of srfi-41 stream-constant.
(define (stream-cycle head)
(apply stream-constant head))
(display (stream->list (stream-take 10 (stream-cycle '(1 2 3)))))
(newline)
(display (stream->list (stream-take 10 (stream-repeat #\X))))
(newline)
(display (stream->list (stream-take 5 (stream-repeat #\Y))))
(newline)
;; Alternate stream-cycle using srfi-41 stream-of.
(define (stream-cycle head)
(stream-of x
(y in (stream-constant head))
(x in (list->stream y))))
(display (stream->list (stream-take 10 (stream-cycle '(1 2 3)))))
(newline)
(display (stream->list (stream-take 10 (stream-repeat #\X))))
(newline)
(display (stream->list (stream-take 5 (stream-repeat #\Y))))
(newline)