我如何从SICP调用Scheme号函数

时间:2009-05-05 20:10:34

标签: scheme sicp

在SICP中,(前2.6)将以下功能描述为“无数字通过”的方式。我正在试图理解这一点。作为起点,如何调用这些函数?我可以用输出为1的某种方式实际应用它们吗? (或任何其他数字?)

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

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

我最初的尝试没有成功:

Welcome to DrScheme, version 4.1.5 [3m].
Language: Simply Scheme; memory limit: 128 megabytes.
> (add-1 (zero))
. . procedure zero: expects 1 argument, given 0
> (add-1 zero)
#<procedure>
> (add-1 1)
#<procedure>
> ((add-1 1))
. . #<procedure>: expects 1 argument, given 0
> 

3 个答案:

答案 0 :(得分:9)

这些代表数字的函数称为教会数字(作为SICP状态)。它们的存在意味着您可以定义一个计算系统(例如lambda演算),而不必将数字作为第一类对象 - 您可以使用函数作为基本对象。这个事实主要是理论上的兴趣;教会数字不是实际计算的好选择。

通过将其他对象作为参数应用,您可以看到教会数字定义的正确性。当你将一个代表n的教会数字应用于函数f时,你会得到另一个函数,它将f应用于其参数n次,例如,对于n = 3,f(f(f(x)))。

> (define (double x) (* 2 x))
> (zero double)
#<procedure>
> ((zero double) 1)
1
> ((zero double) 100)
100
> (define one (add-1 zero))
> ((one double) 1)
2
> ((one double) 100)
200
> (define (cons-a x) (cons 'a x))
> ((zero cons-a) '())
()
> (((add-1 one) cons-a) '(1 2 3))
(a a 1 2 3)

答案 1 :(得分:3)

这是原始的 lambda演算它不会产生数字,它完全用函数替换数字类型。

所以,你有一个'零'功能,如果你给它调用add-1,你就不会得到1,你得到另一个代表1的函数。关键是所产生的函数符合基本算术公理,所以它们等于自然数

答案 2 :(得分:0)

(define (as-primitive-num church-num)
    (define (inc a) (+ a 1))
    ((church-num inc) 0))

;testing:
(define one (add-1 zero))
(define two (add-1 one))

(display (as-primitive-num one)) (newline)
(display (as-primitive-num two)) (newline)

和输出:

    1
    2