Next: , Previous: , Up: streams   [Index]


1.15.10 Unfolding

Function: stream-unfold map pred gen base

stream-unfold is the fundamental recursive stream constructor. It constructs a stream by repeatedly applying gen to successive values of base, in the manner of stream-iterate, then applying map to each of the values so generated, appending each of the mapped values to the output stream as long as (pred base) is non–#f. See also stream-iterate and stream-unfolds.

For example, the expression below creates the finite stream:

0 1 4 9 16 25 36 49 64 81

initially the base is 0, which is less than 10, so map squares the base and the mapped value becomes the first element of the output stream; then gen increments the base by 1, so it becomes 1; this is less than 10, so map squares the new base and 1 becomes the second element of the output stream; and so on, until the base becomes 10, when pred? stops the recursion and stream-null ends the output stream.

(stream-unfold
  (lambda (x) (expt x 2)) ; map
  (lambda (x) (< x 10))   ; pred
  (lambda (x) (+ x 1))    ; gen
  0)                      ; base
Function: stream-unfolds proc seed

Return n newly–allocated streams containing those elements produced by successive calls to the generator proc, which takes the current seed as its argument and returns n+1 values:

(proc seed) -> seed R0 ...  R(n-1)

where the returned seed is the input seed to the next call to the generator and R(i) indicates how to produce the next element of the i-th result stream:

(value)

value is the next car of the result stream;

#f

no value produced by this iteration of the generator proc for the result stream;

()

the end of the result stream.

It may require multiple calls of proc to produce the next element of any particular result stream. See also stream-iterate and stream-unfold.

stream-unfolds is especially useful when writing expressions that return multiple streams. For instance, with reference to the definitions below:

(stream-partition pred strm)

is equivalent to:

(values
  (stream-filter pred strm)
  (stream-filter
      (lambda (x)
        (not (pred x)))
     strm))

but only tests pred once for each element of strm.

(define (stream-partition pred strm)
  (stream-unfolds
    (lambda (s)
      (if (stream-null? s)
          (values s '() '())
        (let ((a (stream-car s))
              (d (stream-cdr s)))
          (if (pred a)
              (values d (list a) #f)
            (values d #f (list a))))))
    strm))

(call-with-values
  (lambda ()
    (stream-partition odd?
      (stream-range 1 6)))
  (lambda (odds evens)
    (list (stream->list odds)
          (stream->list evens))))
⇒ ((1 3 5) (2 4))

Next: , Previous: , Up: streams   [Index]