以下是SICP的练习2.6:
练习2.6:在将成对表示为过程不够令人难以置信的情况下,考虑到在一种可以操作过程的语言中,我们可以通过实现0和加法1作为(定义为零(lambda (f) (lambda (x) x))(定义(add-1 n) (lambda (f) ) (lambda ( f ) (lambda (x) )(lambda(X)(f ((n )x)来实现0和加法1的运算,这样的表示称为教会数字,以其发明者Alonzo Church,发明λ微积分的逻辑学家。直接定义一和二(不是零和加-1)。(提示:使用替换来计算(加-1))。给出加法程序+的直接定义(而不是重复应用add-1)。
请检查我的代码:
(define one (lambda (f) (lambda (x) (f x))))
(define two (lambda (f) (lambda (x) (f (f x)))))
;; I used an identity function to check the + procedure
(define (+ a b)
(lambda (f)
(lambda (x)
((((a f) b) f) x))))
如何改进这段代码?
发布于 2016-09-11 21:36:24
您的函数+
不正确。
两个教会数字之和的定义如下:
(define (plus a b)
(lambda (f)
(lambda (x)
((a f) ((b f) x)))))
(例如,参见维基百科)。
实际上,教会数字n可以定义为将给定函数f
n倍应用于给定值x
的函数。因此,在上述定义中,和(plus a b)
首先将b
倍f
应用于x
,而对于该结果,f
被应用a
倍。相反,在您的定义中,函数体内的应用程序类型是错误的。
如何检验教会数字及其功能的正确性?
您只需将教会数字应用于函数整数后继(即(lambda(x)(+ x 1))
)和数字0,以确定它是否生成相应的“规则”数字。因此,例如:
(define (succ x) (+ x 1)) ;; here `+` is the integer addition, not your function!
((zero succ) 0) ; produces 0
((one succ) 0) ; produces 1 etc.
因此,您可以测试和是否正确:
(((plus one two) succ) 0) ; produces 3
如果您尝试您的函数,您会发现:
(((+ one two) succ) 0) ; raises an error
https://codereview.stackexchange.com/questions/141084
复制相似问题