SICP 習題 (1.41)解題總結

來源:互聯網
上載者:User

標籤:style   class   blog   code   2014   表   

SICP 習題1.41 看似和周邊的題目沒有關係,突然叫我們去定義一個叫double的過程,其實這道題的核心還是高階函數。


題目要求我們定義一個過程double,它以一個過程作為參數,這個作為參數的過程已經約定是一個單參數過程。double過程需要返回一個過程,所返回的過程將傳入的過程應用兩次。


舉例說,如果我們有個過程叫(扇耳光 賤人),調用這個過程會扇賤人一個耳光。

那麼(double 扇耳光)會返回另一個過程,這個過程沒有名字,我們暫且叫他“扇倆耳光”吧,調用(扇倆耳光 賤人)就會扇賤人兩個耳光了。

也就是說((double 扇耳光) 賤人)這樣的調用會扇賤人兩個耳光。


好,題目問我們(((double ( double double)) inc) 5)的結果是什麼,其中inc方法會給傳入參數加1.


要完成這道題,先看看double如何定義吧。


完全按照題目意思,定義的double如下:

(define (double f)  (lambda (x)     (f (f x)))) 

為了測試,我定義了一個我自己的inc過程

(define (my-inc x)  (+ x 1))

最後直接測試

(define test-it (((double ( double double)) my-inc) 5))

結果是21,也就是5+16,就是做了16次加一的操作。


為什麼呢?


我們可以一步一步展開


;首先將不同的double標號,分別是double1 , double2, double3,這樣比較清晰(define step1 (((double1 ( double2 double3)) my-inc) 5));然後將(double2 double3)展開:(define step2 (((double1 (lambda (x) (double3 (double3 x)))) my-inc) 5));將(lambda (x) (double3 (double3 x))) 命名為lam1:(define (lam1 x) (double3 (double3 x)));這樣step2就等同於下面的step3:(define step3 (((double1 lam1) my-inc) 5));再將(double1 lam1)展開:(define step4 (((lambda (x) (lam1 (lam1 x))) my-inc) 5));將my-inc代入step4中得lambda中:(define step5 ((lam1 (lam1 my-inc)) 5));將裡面的lam1還原回原來的定義:(define step6 ((lam1 (double3 (double3 my-inc))) 5));將裡面的(double3 my-inc)展開:(define step7 ((lam1 (double3 (lambda (x) (my-inc (my-inc x))))) 5)); 將step7裡的lambda定義為lam2:(define (lam2 x) (my-inc (my-inc x)));那麼step7可以轉換為:(define step8 ((lam1 (double3 lam2)) 5)); 再將step8中的(double3 lam2)展開得到step9:(define step9 ((lam1 (lambda (x) (lam2 (lam2)))) 5));將step9中得lambda函數定義為lam3:(define (lam3 x) (lam2 (lam2)));那麼step9就可以轉換成step10這樣:(define step10 ((lam1 lam3) 5)); 將step10中的lam1恢複成原來的定義:(define step11 ((double3 (double3 lam3)) 5));將(double3 lam3)展開:(define step12 ((double3 (lambda (x) (lam3 (lam3 x)))) 5));將step12中的lambda函數命名為lam4:(define (lam4 x) (lam3 (lam3 x)));則step12可以表示成step13這樣:(define step13 ((double3 lam4) 5));將(double3 lam4)展開:(define step14 ((lambda (x) (lam4 (lam4 x))) 5));將5代入step14中的lambda過程中:(define step15 (lam4 (lam4 5)));將lam4還原回原始定義:(define step16 (lam3 (lam3 (lam3 (lam3 5)))));將lam3還原回原始定義:(define step17 (lam2 (lam2 (lam2 (lam2 (lam2 (lam2 (lam2 (lam2 5)))))))));將lam2還原回原始定義:(define step18 (my-inc (my-inc (my-inc (my-inc (my-inc (my-inc (my-inc (my-inc (my-inc (my-inc (my-inc (my-inc (my-inc (my-inc (my-inc (my-inc 5)))))))))))))))));結果就是21了:(define step19 21)


以上的分析過程比較繁瑣,不過也比較詳細。


如果從抽象一點的層面來看的話,也可以用另外一種方法

考察以下方法:

(((double ( double double)) my-inc) 5)


double過程的作用是將任何方法嵌套調用兩次。


而(double double)就是將double嵌套調用兩次,結果就是將任何方法嵌套調用4次。

如果有(define four-time (double double))的話,fourtime過程將任何方法嵌套調用4次。

進一步看得話(double (double double))相當於(double four-time)。


相當於是(four-time (four-time x))


這裡要特別注意,兩次four-time的嵌套調用並不是4+4次,而是4*4次調用,就是16次調用。


習題1.41解題完成,這道題也可以很好地協助同學們理解高階函數,特別是高階函數的嵌套。


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.