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就easy定义了,就是定义和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))

SICP 习题 (2.6) 解题总结:丘奇计数的更多相关文章

  1. SICP 习题 (1.13) 解题总结

    SICP习题1.13要求证明Fib(n)是最接近φn/√5 的整数,其中φ=(1+√5)/2 .题目还有一个提示,提示解题者利用归纳法和斐波那契数的定义证明Fib(n)=(φn - ψn) / √5 ...

  2. SICP 习题 (1.7) 解题总结

    SICP 习题 1.7 是对正文1.1.7节中的牛顿法求平方根的改进,改进部分是good-enough?过程. 原来的good-enough?是判断x和guess平方的差值是否小于0.001,这个过程 ...

  3. SICP 习题 (1.14)解题总结

    SICP 习题 1.14要求计算出过程count-change的增长阶.count-change是书中1.2.2节讲解的用于计算零钱找换方案的过程. 要解答习题1.14,首先你需要理解count-ch ...

  4. SICP 习题 (1.8) 解题总结

    SICP 习题1.8需要我们做的是按照牛顿法求平方根的方法做一个求立方根的过程. 所以说书中讲牛顿法求平方根的内容还是要好好理解,不然后面这几道题做起来就比较困难. 反过来,如果理解了牛顿法求平方根的 ...

  5. SICP 习题 (1.9) 解题总结

    SICP 习题 1.9 开始针对“迭代计算过程”和“递归计算过程”,有关迭代计算过程和递归计算过程的内容在书中的1.2.1节有详细讨论,要完成习题1.9,必须完全吃透1.2.1节的内容,不然的话,即使 ...

  6. SICP 习题 (1.10)解题总结

    SICP 习题 1.10 讲的是一个叫“Akermann函数”的东西,去百度查可以查到对应的中文翻译,叫“阿克曼函数”. 就像前面的解题总结中提到的,我是一个数学恐惧者,看着稍微复杂一点的什么函数我就 ...

  7. SICP 习题 (2.7) 解题总结 : 定义区间数据结构

    SICP 习题 2.7 開始属于扩展练习,能够考虑不做,对后面的学习没什么影响.只是,假设上面的使用过程表示序对,还有丘奇计数你都能够理解的话,完毕这些扩展练习事实上没什么问题. 习题2.7是要求我们 ...

  8. SICP 习题 (1.41)解题总结

    SICP 习题1.41 看似和周边的题目没有关系,突然叫我们去定义一个叫double的过程,事实上这道题的核心还是高阶函数. 题目要求我们定义一个过程double,它以一个过程作为參数,这个作为參数的 ...

  9. SICP 习题 (2.10)解题总结: 区间除法中除于零的问题

    SICP 习题 2.10 要求我们处理区间除法运算中除于零的问题. 题中讲到一个专业程序猿Ben Bitdiddle看了Alyssa的工作后提出了除于零的问题,大家留意一下这个叫Ben的人,后面会不断 ...

随机推荐

  1. .net版Git Server --- bonobo

    官网地址: https://bonobogitserver.com/ Demo: http://demo.bonobogitserver.com/Home/LogOn  登入admin:admin C ...

  2. 网站遭遇DDOS简易处理

    网站遭遇DDOS攻击 netstat -an | grep ESTABLISHED 我们看到有大量的链接存在着,并且都是ESTABLISHED状态 for i in `netstat -an | gr ...

  3. Android 计时与倒计时

    方法一 Timer与TimerTask(Java实现) [java]  view plain copy print ?   public class timerTask extends Activit ...

  4. C++数据结构之二叉树

    之前打算编算法类的程序,但是搞了几次英雄会后,觉得作为一个还在学习阶段的学生,实在是太浪费时间了,并不是没意义,而是我的基础还不牢固啊.所以转变了思路,这个学期打算分别用C++.Python.Java ...

  5. 解决Xcode 7编译错误:does not contain bitcode

    连接地址:http://jingyan.baidu.com/article/8065f87f96cf462331249801.html 好不容易更新到Xcode 7.0.1,重新编译代码,报错: do ...

  6. MFC 关于对话框的注意点

    1.对于模态对话框而言,单击确定以后对话框窗口对象即被销毁了,而对于非模态对话框来说,对话框的对象并未销毁而是隐藏起来(EndDialog函数),因此对于非模态对话框,必须重写OnOK这个虚函数,并在 ...

  7. 创建webservice 用service.xml配置(复杂点的方法)

    用Axis2实现Web Service,虽然可以将POJO类放在axis2/WEB-INF/pojo目录中直接发布成Web Service,这样做不需要进行任何配置,但这些POJO类不能在任何包中.这 ...

  8. Swift - 多线程实现方式(3) - Grand Central Dispatch(GCD)

    1,Swift继续使用Object-C原有的一套线程,包括三种多线程编程技术: (1)NSThread (2)Cocoa NSOperation(NSOperation和NSOperationQueu ...

  9. vue.js+boostrap

    vue.js+boostrap最佳实践 一.为什么要写这篇文章 最近忙里偷闲学了一下vue.js,同时也复习了一下boostrap,发现这两种东西如果同时运用到一起,可以发挥很强大的作用,boostr ...

  10. HDU 4293 Groups

    模型挺好的dp题,其实这道题就是建一个模型然后就很容易想到递推过程了,我们可以把每个人的描述,存到数组a中,a[l][r]表示左边有l个,到第r个这个人所在一层停止...然后就可以写出转移状态方程了. ...