123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- (library (stream)
- (export make-stream
- stream-value
- stream-index
- stream-next-proc
- stream-next
- stream-get-nth-value
- stream-map
- stream-pos
- stream->list)
- (import
- (except (rnrs base) let-values map)
- (only (guile)
- lambda* λ)
- ;; structs
- (srfi srfi-9)
- ;; for functional structs (not part of srfi-9 directly)
- (srfi srfi-9 gnu))
- (define-immutable-record-type <stream>
- (make-stream val
- index
- previous-input
- next-input
- next-output)
- stream?
- ;; val is the value of the last application of the next
- ;; procedure.
- (val stream-value)
- ;; index is the current index in the stream.
- (index stream-index)
- ;; Store the previous input, to enable things like
- ;; counting up, regardless of what the output value is
- ;; and basing the next output value on another value
- ;; than the output value. For example one might want to
- ;; output all square numbers.
- (previous-input stream-previous-input)
- ;; next-input is the procedure, which gets the next
- ;; input value for next-proc.
- (next-input stream-next-input-proc)
- ;; next-proc is the procedure, which calculates the next
- ;; value.
- (next-output stream-next-output-proc))
- (define stream-next
- (λ (stream)
- (let ([val (stream-value stream)]
- [index (stream-index stream)]
- [previous-input (stream-previous-input stream)]
- [next-input-proc (stream-next-input-proc stream)]
- [next-output-proc (stream-next-output-proc stream)])
- (make-stream
- ;; The output of the stream is based on the input,
- ;; ...
- (next-output-proc
- ;; ... which is calculated using the previous
- ;; input, the previous output value, or the index
- ;; of the stream.
- (next-input-proc val index previous-input))
- (+ index 1)
- (next-input-proc val index previous-input)
- next-input-proc
- next-output-proc))))
- (define stream-get-nth-value
- (λ (stream n)
- (cond
- [(= n 0)
- (stream-value stream)]
- [else
- (stream-get-nth-value (stream-next stream)
- (- n 1))])))
- (define stream-map
- (λ (proc base)
- (make-stream
- ;; make sure proc is already mapped to the first
- ;; value
- (proc (stream-value base))
- ;; index of the new stream starts at zero
- 0
- (stream-previous-input base)
- (stream-next-input-proc base)
- ;; Wrap the base stream's function for calculating
- ;; an output value using the provided mapped proc,
- ;; effectively applying proc to every value the
- ;; base stream would produce.
- (λ (input)
- (proc
- ((stream-next-output-proc base) input))))))
- (define stream-pos
- (λ (elem a-stream)
- (let iter ([stream a-stream] [n 0])
- (cond
- [(equal? (stream-value stream) elem) n]
- [else
- (iter (stream-next stream)
- (+ n 1))]))))
- (define stream->list
- (λ (stream max-num-elems)
- (cond
- [(= max-num-elems 0) '()]
- [else
- (cons (stream-value stream)
- (stream->list (stream-next stream) (- max-num-elems 1)))]))))
|