随机流:何时进行评估?

问题描述 投票:2回答:1

我认为以下代码应定义1到10之间的随机数流:

(define random-stream (stream-cons (random 1 11) random-stream))

但是,它实际上的作用是定义特定随机数的流。例如:

> (stream->list (stream-take random-stream 10))
'(5 5 5 5 5 5 5 5 5 5)

我想这是(random 1 11)首次解析定义时产生的随机数。我通过使random-stream一个无参数的函数来解决这个问题:

(define (random-stream) (stream-cons (random 1 11) (random-stream)))

此作品:

> (stream->list (stream-take (random-stream) 10))
'(6 1 10 9 4 2 2 3 3 10)

因此,在我看来,可以理解,常量是在读取时求值的,而函数是在调用时求值的。通常这无关紧要,但是在流的情况下(您具有递归定义)会有所不同。

这是如何工作的,还是比这更微妙的?还有其他情况需要注意这一差异吗?

random stream scheme racket
1个回答
1
投票

使random-stream无参函数是正确的解决方案。

(define (random-stream) (stream-cons (random 1 11) (random-stream)))

我将解释原因。

通常使用(define my-stream (stream-cons ....))定义流时,该流只有一个值。对my-stream的任何引用都将产生相同的值。

(define my-stream (stream-cons (random 1 11) my-stream))

“ rest”内的my-stream实际上是与eq?相同的值my-stream

> (eq? my-stream (stream-rest my-stream))
#true

因此,因为它们是相同的值,所以可以在函数调用中将它们替换。如果(stream-first my-stream)返回5,则(stream-first (stream-rest my-stream))也必须返回5。

> (eq? (stream-first my-stream) (stream-first (stream-rest my-stream)))
#true

函数版本不是这种情况,因为每次调用该函数都会创建一个新的流值。

(define (random-stream) (stream-cons (random 1 11) (random-stream)))

> (eq? (random-stream) (random-stream))
#false
> (eq? (stream-first (random-stream)) (stream-first (random-stream)))
#false

由于“ rest”字段也称为(random-stream),所以其余部分与整体不同。

> (define generated-stream (random-stream))
> (eq? generated-stream (stream-rest generated-stream))
#false
> (eq? (stream-first generated-stream) (stream-first (stream-rest generated-stream)))
#false
© www.soinside.com 2019 - 2024. All rights reserved.