计划中教会数字的递归

时间:2015-10-02 03:58:06

标签: recursion scheme lambda-calculus church-encoding

根据维基百科的定义,我已将教会数字零和其他一些标准函数定义为教会数字:

(define n0 (λ (f x) x))

(define newtrue
  (λ(m n) m))

(define newfalse
  (λ(m n) n))

(define iszero
  (λ(m) (m (λ(x) newfalse) newtrue)))

(define ifthenelse
  (λ(a b c) (a b c)))

使用这些,我写一个递归循环:

(((λ(r) (λ(n) (ifthenelse (iszero n) n ((r r) n))))
   (λ(r) (λ(n) (ifthenelse (iszero n) n ((r r) n))))) n0)

现在对于参数n0,如上所述,这应返回n0,而不进行递归。但它并没有。为什么呢?

注1:这个递归循环与普通数字和普通函数完美配合:

(((λ(r) (λ(n) (if (= 0 n) n ((r r) n))))
   (λ(r) (λ(n) (if (= 0 n) n ((r r) n))))) 0)

这将返回0

注2:函数ifthenelseiszeronewtruenewfalse也可以自行运行。

1 个答案:

答案 0 :(得分:0)

循环的原因是Scheme中函数的语义总是评估它的所有参数。

在你的第二个例子中:

(((λ(r) (λ(n) (if (= 0 n) n ((r r) n))))
   (λ(r) (λ(n) (if (= 0 n) n ((r r) n))))) 0)

您正在使用if,这是一种特殊形式,如果条件为真,则评估第三个参数。因此,它评估(= 0 n)并立即返回0,因为条件为#true,而不评估第三个参数((r r) n)

相反,在第一个例子中:

(((λ(r) (λ(n) (ifthenelse (iszero n) n ((r r) n))))
   (λ(r) (λ(n) (ifthenelse (iszero n) n ((r r) n))))) n0)

ifthenelse是一个函数,因此,根据Scheme的评估规则, all 会对其参数进行求值,包括((r r) n),这会导致无限循环。