2009-05-05 47 views
1

在SICP(例如2.6)中,下面的函數被描述爲'無法取數字'的方式。我在試圖理解這一點。作爲一個起點,這些函數是如何被調用的?我可以在輸出爲1的某種方式實際應用它們嗎? (或任何其他數字?)我如何從SICP調用方案編號功能

(define zero (lambda (f) (lambda (x) x))) 

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

我最初的嘗試都沒有成功:

Welcome to DrScheme, version 4.1.5 [3m]. 
Language: Simply Scheme; memory limit: 128 megabytes. 
> (add-1 (zero)) 
. . procedure zero: expects 1 argument, given 0 
> (add-1 zero) 
#<procedure> 
> (add-1 1) 
#<procedure> 
> ((add-1 1)) 
. . #<procedure>: expects 1 argument, given 0 
> 
+0

你可能wan't看http://en.wikipedia.org/wiki/Lambda_calculus#Arithmetic_in_lambda_calculus – 2009-05-05 21:08:02

回答

3

這是當初演算也不會產生數字,它完全取代了數鍵入功能。所以,你有一個'零'功能,如果你打電話給add-1,你不會得到1,你會得到另一個代表1的函數。重點是產生的函數符合基本的算術公理,所以它們相當於自然數

9

這些代表數字的函數被稱爲教會數字(作爲SICP狀態)。它們的存在意味着你可以定義一個計算系統(比如lambda微積分),而不需要把數字作爲第一類對象 - 你可以使用函數作爲原始對象。這個事實主要是理論上的興趣;教會的數字不是實際計算的好選擇。

通過將其與其他對象作爲參數應用,您可以看到您的教會數字定義的正確性。當你將一個代表n的教會數字應用於一個函數f時,你會得到另一個函數,將f應用到它的參數n次,例如,對於n = 3,f(f(f(x)))。

> (define (double x) (* 2 x)) 
> (zero double) 
#<procedure> 
> ((zero double) 1) 
1 
> ((zero double) 100) 
100 
> (define one (add-1 zero)) 
> ((one double) 1) 
2 
> ((one double) 100) 
200 
> (define (cons-a x) (cons 'a x)) 
> ((zero cons-a) '()) 
() 
> (((add-1 one) cons-a) '(1 2 3)) 
(a a 1 2 3) 
+1

彭羅斯包括這皇帝的新思維,我認爲這只是使用不同字體的藉口。 (在書中他將大寫字體中的數字表示爲「零」和「一」) – 2009-05-05 20:56:12

0
(define (as-primitive-num church-num) 
    (define (inc a) (+ a 1)) 
    ((church-num inc) 0)) 

;testing: 
(define one (add-1 zero)) 
(define two (add-1 one)) 

(display (as-primitive-num one)) (newline) 
(display (as-primitive-num two)) (newline) 

和輸出:

 
    1 
    2