Scheme 中的流问题

Trouble with streams in Scheme

我正在尝试编写一个流,它将无限流 S 和两个整数 mn 以及 returns 作为参数的流元素是 S 的元素,它们是 mn.

的倍数

不幸的是,我的流只在找到第一个倍数之前有效,然后它就不会继续前进。我在调用流时调用 cdr,所以我不确定为什么我不查看下一个元素。

(define stream-car car)
(define (stream-cdr s)
  ((cadr s)))

(define (divisible? n x)
  (zero? (remainder n x)))
(define (stream-cons x s)
  (list x (lambda () s)))

;should loop to find the next multiple in the parameter stream
(define (findnext s m n)
  (if (or (divisible? (stream-car s) m) 
          (divisible? (stream-car s) n))
      (stream-car s)
      (findnext (stream-cdr s) m n)))

;this is my stream
(define (multiples s m n)
  (let ((h (findnext s m n))) 
        ;first need to make sure h is a multiple of 
        ;either m or n, THEN create the list
    (list h
          (lambda ()
            (multiples (stream-cdr s) m n)))))

;below is for testing 
(define (even-nums-from n)
  (list n
        (lambda ()
          (even-nums-from (+ 2 n)))))

(define even-integers
  (even-nums-from 0))

;test cases
(multiples even-integers 4 6);should be a stream with car = 0
(stream-car (multiples even-integers 4 6));should be 0
(stream-cdr (multiples even-integers 4 6));should be a stream with car = 4
(stream-car (stream-cdr (multiples even-integers 4 6))) ;should be 4
(stream-cdr (stream-cdr (multiples even-integers 4 6))) ;should be a stream 
                ;starting with 6-not moving past when we find a multiple
(stream-car (stream-cdr (stream-cdr (multiples even-integers 4 6))))
                ;should be 6 

我对上述测试的输出是:

(list 0 (lambda () ...))
0
(list 4 (lambda () ...))
4
(list 4 (lambda () ...))
4

我正在使用 DrRacket(高级学生语言),只是不确定为什么我的流卡在第一个倍数 (4) 上。当我再次调用倍数时,我正在调用 stream-cdr,所以我不明白我哪里出错了。任何想法将不胜感激。

解决了,问题是我没有更新传递的流,因为我找到了下一个倍数。下面是更正后的代码(我现在在我的 multiples 函数中使用汽车中的倍数传递一个流):

;returns the stream with car a multiple of either m or n
(define (findnext s m n)
  (cond ((divisible? (stream-car s) m) s)
        ((divisible? (stream-car s) n) s)      
        (else (findnext (stream-cdr s) m n))))

(define (multiples s m n)
  (let ((h (findnext s m n))) ;h is now an updated stream 
                              ;with car a multiple of one of m or n
    (list (stream-car h)
          (lambda ()
            (multiples (stream-cdr h) m n)))))