2014-01-12 89 views
0

這個問題可以在http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-12.html#%_thm_1.37無法在SICP評估lambda表達式作爲參數前1.37

發現的問題是擴張的持續分數以便接近披。這意味着你的程序應該能夠通過評估計算披:

(cont-frac (lambda (i) 1.0) 
      (lambda (i) 1.0) 
      k) 

我的解決方案如下:

(define (cont-frac n d k) 
(if (= k 1) d 
    (/ n (+ d (cont-frac n d (- k 1)))))) 

時調用此方法適用於(續壓裂111 K),但不當問題表明使用lambda表達式時。我得到什麼看起來像一個類型的錯誤

;ERROR: "ex-1.37.scm": +: Wrong type in arg1 #<CLOSURE <anon> (x) 1.0> 
; in expression: (#@+ #@d (#@cont-fraC#@n #@d (#@- #@k 1))) 
; in scope: 
; (n d k) procedure cont-frac 
; defined by load: "ex-1.37.scm" 

;STACK TRACE 
1; ((#@if (#@= #@k 1) #@d (#@/ #@n (#@+ #@d (#@cont-fraC#@n #@d ... 

我的問題是兩部分:

問題1:爲什麼我使用拉姆達參數,當我得到這個錯誤?我(錯誤地肯定)認爲(lambda(x)1)應該評估爲1.它顯然沒有。我不確定我是否理解它做了什麼評估:我認爲它沒有評估任何東西(即「返回一個值」 - 也許是錯誤的術語),而沒有通過x的參數。

它仍然沒有答案爲什麼你會有一個lambda返回一個常量。如果我理解正確,(lambda(x)1.0)將始終評估爲1.0,而不管x是什麼。那麼爲什麼不把1.0放在一起呢?這導致:

問題2.我爲什麼要使用它們?我懷疑這會在我看過的1.38版本中有用,但我不明白爲什麼使用(lambda(x)1.0)與使用1.0有什麼不同。

回答

2

在方案lambda表達式創建了一個函數,因此表達如:

(lambda (i) 1.0) 

確實有結果,這是一個函數對象 但如果添加周圍的表達括號,它的確會如你預期評估,以1.0

((lambda (i) 1.0)) 

在練習中使用lambda表達式對於構建一般解決方案非常必要,正如您在練習1.38中正確注意到的那樣,您將使用與cont-frac函數相同的實現,但具有不同的分子和分母函數,您將看到一個示例,在這裏你應該使用循環計數器在運行時計算其中的一個。

您可以將您的運動方案與我的運動方案進行比較,例如: 1.371.38

+1

在你的1.37中,你應該用值k和0來調用它,而不是k和1 – WorBlux

+0

固定,謝謝。在遞歸函數代碼中發現另一個問題。 – maxbublis

0
(/ n (+ d (cont-frac n d (- k 1)))))) 

在這種情況下,「d」是拉姆達聲明,它沒有任何意義「+」它,同樣爲「n」和「/」嘗試像

(/ (n k) (+ (d k) (cont-frac n d (- k 1)))))) 

你會明白爲什麼在下一個練習中你也可以做這個尾遞歸

我給變量Fd和Fn命名,而不是d和n,因爲它們接受計算分子和分母項的函數。 (lambda(i)1.0)是一個接受一個參數並返回1.0的函數,1.0只是一個數字。在其它續的級分,該值可與深度(因此爲什麼需要傳遞k以分子和denomenator函數來計算正確的術語變化