我可以使用方案相当容易地定义教堂数字:
> (define f (lambda (x) x))
> (f f) ;0
#<procedure:f>
> (f (f f)) ;1
#<procedure:f>
但是,这并不容易识别(f f)
0 和 (f (ff)) 是 1。有没有办法让这些数字更具可读性?理想的情况是:
> (f f)
0
> (f (f f))
1
该示例在方案中,但我会在任何 lisp 中回答。
我可以使用方案相当容易地定义教堂数字:
> (define f (lambda (x) x))
> (f f) ;0
#<procedure:f>
> (f (f f)) ;1
#<procedure:f>
但是,这并不容易识别(f f)
0 和 (f (ff)) 是 1。有没有办法让这些数字更具可读性?理想的情况是:
> (f f)
0
> (f (f f))
1
该示例在方案中,但我会在任何 lisp 中回答。
首先让我们定义真正的教堂数字,它们具有以下理想属性0 != 1
:
(define zero (lambda (f x) x))
(define (succ cn) (lambda (f x) (f (cn f x))))
0、1、2 等的zero
教会表示也是如此。(succ zero)
(succ (succ zero))
现在,由于这些只是函数,因此无法告诉 repl 将它们显示为数字,但您可以定义一个函数 cn-to-int 将教堂数字转换为可以正常显示的整数:
> (define (cn-to-int cn) (cn (lambda (x) (+ x 1)) 0))
> (cn-to-int zero)
0
> (cn-to-int (succ zero))
1
> (cn-to-int (succ (succ zero)))
2