2016-05-22 1 views
2

У меня есть домашнее задание, что я немного потерял. Учитывая поток натуральных чисел, я должен иметь возможность создавать новый поток (дважды в потоке), где все элементы умножаются на два.Умножение потока в схеме Petite

(define stream-of-natural-numbers 
    (letrec ([produce (lambda (current-natural-number) 
        (cons current-natural-number 
         (lambda() 
          (produce (1+ current-natural-number)))))]) 
(produce 0))) 

Я придумал следующий код, но ничего не работает, и теперь я потерялся.

(define twice-the-stream 
    (lambda (n) 
     (letrec ([produce (lambda (current next) 
           (cons (* 2 current) 
            (lambda() 
             (produce (current next) (force (next))))))]) 
    (produce (car n) (force (cdr n)))))) 

(дважды поток в поток из натуральных чисел)

Что мне не хватает?

ответ

1
(define twice-the-stream 
    (lambda (n) 
     (letrec ([produce (lambda (current next) 
           (cons (* 2 current) 
            (lambda() 
             (produce (current next) (force (next))))))]) 
           ;; this is wrong: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
    (produce (car n) (force (cdr n)))))) 

Вы уже нанесли (cdr n) в этот момент; теперь next не является функцией, это поток - минусовая пара его текущий номер и его поток-хвост.

current также не является функцией. Это номер, уже используемый для создания удвоенного номера выше этого звонка.

Чтобы уменьшить когнитивную нагрузку, переименовывать переменные, чтобы напомнить вам, что они есть,

(define twice-the-stream 
    (lambda (numbers-stream) 
     (letrec ([produce (lambda (current-num next-str) 
           (cons (* 2 current-num) 
            (lambda() 
             (produce (current-element next-str) 
               (force (next-elements next-str))))))]) 
    (produce (car numbers-stream) (force (cdr numbers-stream)))))) 

и теперь вы можете видеть, что вы запутались по чрезмерно наводящим (и под специализированные) именовании, объединив в своем уме «текущий» номер с функцией «текущий номер» и «следующий» поток с функцией «следующий поток». Разбивая заклинание, теперь ясно, что нужно сделать, чтобы привести два вызова produce в синхронизацию.

Кстати, если бы вы использовали более короткие имена переменных - в первую очередь, ns для «потока чисел», n для «ряда», s для «потока», вы бы иметь немного меньше шансов запутаться,

(define twice-the-stream 
    (lambda (ns) ;; a numbers stream 
     (letrec ([produce (lambda (n s) ; a number, and a stream 
           (cons (* 2 n) ; a number, doubled 
            (lambda() ; a stream, repackaged: 
             (produce (.... s) ; _its_ 1st element 
               (force (.... s))))))]) ; and the rest 
    (produce (car ns) (force (cdr ns)))))) 

так делать то, что вы должны делать (предположительно) - то есть, используя описательные имена (но не достаточно описательные) - это то, что у вас в эта проблема во-первых!


якобы не очень хорошая вещь - но до тех пор, как они четко описаны в комментариях, я не понимаю, почему это должно быть так.

Смежные вопросы