SICP 习题 (2.6) 解题总结:丘奇计数

88 篇文章 30 订阅
74 篇文章 0 订阅

SICP 习题 2.6 讲的是丘奇计数,是习题2.4 和 2.5的延续。 这里大师们想提醒我们思考的是“数”到底是什么,在计算机系统里可以如何实现“数”,准备好开始脑洞大开吧:


题目先讲到下面的定义,首先是0的定义:


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

然后是操作+ 1的定义:

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


接着题目就要求我们根据以上的过程开始定义数 1  和 2, 然后再定义基本的+操作。


说实话,第一次看到这道题的时候我对着上面三行代码看了半天也是稀里糊涂的,搞不清楚这样的代码和数字有什么关系。

其中一个关键是我总是希望zero能够被输出为0,而(add-1 zero)过程会输出一个数字1。


有谁说过只有符号0才代表数字“零”呢?一个空空的口袋不能代表“零”吗? 又有谁说过只有符号1才代表数字“壹”呢?在苍茫大地上孤独行走的我不能代表“壹”吗?


把你的脑洞开到这个程度差不多你就可以理解丘奇计数了。


丘奇计数的基本想法就是通过调用0次函数来表示0,通过调用1次函数来表示1,以此类推。。。


所以,这里的zero其实是一个lambda过程,该过程接受另一个过程作为参数,不过对该过程调用0次,什么叫调用0次呢,就是传人什么参数就返回什么参数喽。


对应的,(add-1 n)过程也是返回一个lambda过程,该过程接受另一个过程作为参数,对该过程调用n+1次。


这样理解的话,1和2就容易定义了,就是定义和zero类似的lambda过程,不过这次分别是调用1次和2次传入的过程,代码如下:

 

(define one
  (lambda (f) (lambda (x) (f x))))

(define two
  (lambda (f) (lambda (x) (f (f x)))))


借着是要考虑如何实现+的操作,我们知道丘奇计数里的“数”其实就是调用传入过程的次数,那就比较简单,如果要将两个丘奇计数中的数n和m加起来,其实就是对传入过程调用(n+m)次。用下面这样的简单嵌套就可以实现了:


(define (plus first second)
    (lambda (f)
        (lambda (x)
             ((first f) ((second f) x)))))



最后你可能会有疑问,像这样的计数有什么意义吗?

其实这里体现的是更高阶的“数”的理解,我们可以通过简单的办法降阶。我们可以定义下面这样一个接近于无聊的过程:

  (define (f x)
    (display "*")
    )


这个过程只接受一个参数,过程体什么都不做,只是打印一个*号。


因为丘奇计数其实计算的是过程的调用次数,所以如果我们将以上过程使用在丘奇计数中,就可以通过打印出来的*号直观地感受到丘奇计数中“数”的概念。


比如执行((two f) ‘a)会打印2个*号。

执行((one f) ‘a)会打印1个*号。


更多调用样例请参考以下代码:


(define (start-test-2-6)
  
  (display "going to display 1:")(newline)
  ((one f) 'a)(newline)
  (display "going to display 2:")(newline)
  ((two f) 'a) (newline)
  (display "going to display 1+2:")(newline)
  (((plus one two) f) 'a)
  (newline)
  (display "going to display 1+2+2")(newline)
  (((plus (plus one two) two) f) 'a)
  (newline)

  (display "end.") (newline))

  


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值