根据维基百科的定义,我已将教会数字零和其他一些标准函数定义为教会数字:
(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:函数ifthenelse
,iszero
,newtrue
,newfalse
也可以自行运行。
答案 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)
,这会导致无限循环。