2016-05-22 23 views
2

我得到了一些家庭作業,我有點失落。給定一串自然數,我應該能夠產生一個新的流(流的兩倍),其中所有的元素都乘以2。在嬌小的計劃中的流的乘法

(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呼叫同步。

順便說一句,如果你想使用更短的變量名放在首位1ns爲「數字流」,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)))))) 

這樣做你應該做的做(據說) - 即使用描述性的名字(但不足夠的描述) - 是什麼讓你進入這個麻煩在第一位!


按說不是什麼好東西 - 但只要他們在評論中明確說明,我不明白爲什麼這應該是這樣。