SICP 習題2.6之丘奇數

 最近一直在閱讀《SICP》,而後下午作其中的習題2.6,對其題意很不理解,因而搜索了相關資料,不由如題設所說感到如雷灌頂,特此記錄下來,以供你們閱讀和交流html

題目

 若是以爲將序對錶示最爲過程還不足以使人如雷灌頂,那麼請考慮,在一個能夠對程序作各種操做的語言中,咱們徹底能夠沒有數(至少在只考慮非整數的狀況下),能夠將0和加一操做實現爲:wordpress

(define zero (lambda (f) (lambda (x) x)))
(define (add-1 n)
    (lambda (f) (lambda (x) (f ((n f) x)))))

這一表現形式稱爲Church計數,名字來源於其發明人數理學家Church,請直接定義one和two(不使用zero和add-1)(提示:利用代換法去求值)。請給出加法過程+的一個直接定義(不要反覆應用add-1)函數

丘奇數

 說實話,我一直沒有看懂題目中關於zero和add-1的定義,因而我搜索了相關資料。下邊就結合資料談一下它的概念。
 首先要明確的是丘奇數中的zero,one等並不等同於數值上的0,1,2。你能夠理解爲它是零這個概念的一種表現形式。換句話說,它就是零的函數式表現形式。咱們先來看一下丘奇數中zero,one和two的表現形式code

(define zero
  (lambda (f) (lambda (x) x)))
(define one
  (lambda (f) (lambda (x) (f x))))
(define two
  (lambda (f) (lambda (x) (f (f x)))))

 咱們會發現zero,one和two都是一個函數,它接收(f)做爲參數,其結果是一個接收(x)做爲參數的函數。你們可能須要注意的是,(f)在這裏顯然也是一個函數,在LISP中函數是能夠做爲輸入參數的。而後咱們會發現zero,one和two的區別好像就是(f)函數被使用的次數。zero中(f)沒有被使用,one中(f)使用了一次,two中(f)使用了兩次,對就是這個次數來表示0,1,2的概念。
 咱們能夠實驗一下檢驗一下htm

(define (inc n)
   (+ n 1))
> ((zero inc) 0)
0
> ((zero inc) 1)
1
> ((one inc) 1)
2
> (((add-1 one) inc) 1)
3

 咱們定義一個過程inc就是數值意義上的加一,而後使用zero,one和add-1發現確實如同咱們所想的,zero表示inc過程不會被使用,返回原數值;one表示inc被使用一次,返回加一的數值。three

替換法求two

 咱們來使用替換法經過add-1和zero來求解one吧。get

(add-1 zero)
;展開add-1定義
(lambda (f) (lambda (x) (f ((zero f) x))))

; 替換zero
(lambda (f) (lambda (x) (f ((lambda (x) x) x))))

; 簡化由於((lambda (x) x) x)就等於x
(lambda (f) (lambda (x) (f x)))

加法定義

 首先咱們要明白丘奇數加法的含義,咱們先記其加法爲add-church,那麼以下代碼所示,最後一個過程得出的值應該是多少呢?class

> ((one inc) 1)
2
> ((two inc) 1)
3
> (((add-church one two) inc) 1)
?

 根據猜想,應該是4吧。由於one表示inc對1這個數值使用一次,two標示使用兩次,那麼將兩者加起來,那麼就應該是three的含義啦,就是表示inc對1這個數值使用3次,那麼就是4啦。
 add-church的實現以下lambda

(define (add-church m n)
   (lambda (f) (lambda (x) ((m f) ((n f) x)))))

 若是你將其與add-1進行對比,你會發現add-1中的f變成了(m f),若是吧add-1中的f記住(one f),你可能就會更加理解。那麼你就會想add-m是如何標示的呢?搜索

參考資料
https://pfmiles.wordpress.com/2009/11/12/%E9%80%90%E6%AD%A5%E7%90%86%E8%A7%A3%E4%B8%98%E5%A5%87%E6%95%B0%E4%B8%80/
http://www.billthelizard.com/2010/10/sicp-26-church-numerals.html

相關文章
相關標籤/搜索