Hello,
some months ago, when I started working with streams, I developed a procedure that takes some single valued streams and return a multi valued stream. Then I thought if the opposite was possible: create a procedure that takes a multi valued stream and return a list of single valued streams. Probably such a procedure isn't very useful, but the solution is interesting.
I developed some macros to deal with multiple values:
(define-syntax values->list ;I didn't use this, but is a good starting point
(syntax-rules ()
[(_ (values lst ...))
(call-with-values
(lambda () (values lst ...))
(lambda v v))]))
(values->list (values 1 2 3))
=> '(1 2 3)
(define-syntax num-of-values
(syntax-rules ()
[(_ (values lst ...))
(call-with-values
(lambda () (values lst ...))
(lambda v (length v)))]))
(num-of-values (values 1 2 3))
=> 3
(define-syntax values-ref
(syntax-rules ()
[(_ (values lst ...) n)
(call-with-values
(lambda () (values lst ...))
(lambda v (list-ref v n)))]))
(values-ref (values 1 2 3) 1)
=> 2
With these procedures the solution is simple:
(define (stream-select the-stream n)
(if (stream-empty? the-stream)
empty-stream
(stream-cons (values-ref (stream-first the-stream) n)
(stream-select (stream-rest the-stream) n))))
(define (mv-stream->list-of-streams the-stream)
(define num-of-vals (num-of-values (stream-first the-stream)))
(let next-streams ([n 0])
(if (= n num-of-vals)
'()
(cons (stream-select the-stream n)
(next-streams (+ n 1))))))
(define mv-stream (stream (values 1 10 100)
(values 2 20 200)
(values 3 30 300)
(values 4 40 400)))
(define los (mv-stream->list-of-streams mv-stream))
(stream->list (first los))
(stream->list (second los))
(stream->list (third los))
'(1 2 3 4)
'(10 20 30 40)
'(100 200 300 400)
Matteo