[racket] taking from a generator, and a possible bug
On 2012-08-18 21:59:28 -0700, Ian Tegebo wrote:
> (take k (in-generator (infinite-generator (yield (random n)))))
>
> where k and n are positive integers, k<n.
>
> Unfortunately, 'in-generator' returns a sequence while 'take' needs a
> list and calling 'sequence->list' results in an error.
One way to get around this without using the `lazy` language is to use
stream functions. Sequences can be converted to streams, which are
general things that can be `first` and `rest`ed.
Here's a simple implementation of `stream-take`:
(define (stream-take st n)
(if (= n 0)
'()
(stream-cons (stream-first st)
(stream-take (stream-rest st)
(sub1 n)))))
You can use it like this:
(define st
(sequence->stream
;; in-producer works here. in-generator's body expects
;; a yielding expression, not a generator object
(in-producer
(infinite-generator
(yield (random 10)))
(lambda (x) #f))))
(stream-take st 10)
This will work, but produces an opaque stream. Use stream accessors or
`stream->list` to get at its elements. This is the best that can be done
with the current stream API because it can't build a stream of the "same
type" right now (e.g., `stream-map` on a list is no longer a list).
I'm not sure if there is a good reason that `stream-take` is not in the
stream library already.
Cheers,
Asumu