Проблема с потоками в схеме

#stream #scheme #racket #lazy-sequences

#поток #схема #ракетка #ленивые последовательности

Вопрос:

Я пытаюсь написать поток, который принимает в качестве аргументов бесконечный поток S и два целых m числа и n , и возвращает поток, элементами которого являются элементы S , кратные либо m или n .

К сожалению, мой поток работает только до тех пор, пока я не найду первое множественное число, тогда оно не продвинется дальше этого. Я вызываю 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 (advanced student language) и просто не уверен, почему мой поток застрял на этом первом кратном (4). Я вызываю stream-cdr, когда снова вызываю кратные числа, поэтому я не понимаю, где я ошибаюсь. Любые идеи будут высоко оценены.

Ответ №1:

Решаемая проблема заключалась в том, что я не обновлял переданный поток, поскольку нашел следующий множественный. Ниже приведен исправленный код (где я теперь передаю поток с кратным в машине, который будет использоваться в моей 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)))))