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. StreamWrite-StreamRead 读写文本文件

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  2. boost中asio网络库多线程并发处理实现,以及asio在多线程模型中线程的调度情况和线程安全。

    1.实现多线程方法: 其实就是多个线程同时调用io_service::run for (int i = 0; i != m_nThreads; ++i)        {            boo ...

  3. const与define的使用区别

    1.const用于类成员变量定义,一旦定义且不能改变其值.define定义全局常量,在任何地方都可以访问. 2.define不能在类中定义而const可以. 3.const不能在条件语句中定义常量 i ...

  4. HDU ACM 1098 Ignatius's puzzle

    分析:裴蜀定理,a,b互质的充要条件是存在整数x,y使ax+by=1.存在整数x,y,使得ax+by=c.那么c就是a,b的公约数. 如果存在数a ,由于对随意x方程都成立.则有当x=1时f(x)=1 ...

  5. 黑马程序猿 ---------- Java网络技术之 ---正則表達式 (Day06)

    ---------------------- ASP.Net+Unity开发..Net培训.期待与您交流. ---------------------- 正則表達式 正則表達式:基本知识 1  字符, ...

  6. WF4.0——升级技能:托付应用

    回想: 在一个月前,我们刚刚回想了面对象至关重要的部分:托付,详细请移步我们博客:面向对象--一起来复习托付与事件!关于这篇博客的详细内容,不再赘述,在这里我们主要讨论在工作流中的应用及他的详细怎样解 ...

  7. hdu1003 最大连续子序和

    Description Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum of a sub ...

  8. 不包含SDK头文件, 补全API定义

    /// @file main.cpp /// @brief 不包含SDK头文件, 补全API定义 #ifdef __cplusplus extern "C" { #endif /* ...

  9. inode结构体成员详解

    概述:inode译成中文就是索引节点,它用来存放档案及目录的基本信息,包含时间.档名.使用者及群组等.inode分为内存中的inode和文件系统中的inode,为了避免混淆,我们称前者为VFS ino ...

  10. Unity3D手游-横版ACT游戏完整源代码下载

    说明: 这不是武林.这不是江湖,没有道不完的恩怨,没有斩不断的情仇,更没有理不清的烦恼,这是剑的世界,一代剑魁闯入未知世界,将会为这个世界展开什么样的蓝图.让你来创造它的未来,剑魁道天下,一剑斗烛龙! ...