高阶函数和church计数

在SICP的第二章的2.06有一个church计数的题目,非常有意思。  题目是这样的:
 
定义0为:
(define zero (lambda (f) (lambda (x) x)))
定义加一操作为:
(define (add1 n)
  (lambda (f) (lambda (x) (f ((n f) x)))))

给出1和2的定义。

one就是(add-1 zero),为:

(lambda (f) (lambda (x) (f x)))

one跟zero的差别就是对x多了一次f处理,可以猜一下,two应该是:

(lambda (f) (lambda (x) (f (f x))))


tow就是对x做了2次f处理。如果用替换模型,结果也确实如此。

按照这个模型,用church计数方法,整数n应该有n个f:

(lambda (f) (lambda (x) (f (f ... (f (f x))))

题目提出要实现church计数的加法,两个church计数相加:

(add n1 n2)

就是f函数的次数相加。

例如one和two相加,就是要把(f x) + (f (f x))弄成 (f (f (f x)))。

可以看到,如果能把(f x)中的x换成(f (f x))就可以了。而

(f (f x)) = 
((lambda (x) (f (f x))) x) = 
(((lambda (f) (lambda (x) (f (f x)))) f) x) = 
((two f) x)

那要把n2加到n1上,就是 

(f ((two f) x)) = ((one f) ((two f) x))

最后加上f和x的参数,就成了:

(lambda (f) (lambda (x) ((one f) ((two f) x))))

所以church计数的加法就是

(define (add n1 n2)
  (lambda (f) (lambda (x) ((n1 f) ((n2 f) x)))))

church计数看上去没什么用,但是如果实现了church计数的加法,可以得到对函数的重复调用的高阶函数。

posted @ 2013-08-27 11:54  yametech  阅读(496)  评论(0编辑  收藏  举报