【问题标题】:Recursion for church numerals in scheme方案中教堂数字的递归
【发布时间】:2015-10-02 03:58:06
【问题描述】:

我根据维基百科的定义定义了教堂数字零和教堂数字的其他一些标准功能,如下所示:

(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 也可以单独工作。

【问题讨论】:

    标签: recursion scheme lambda-calculus church-encoding


    【解决方案1】:

    循环的原因是 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的求值规则,所有它的参数都会被求值,包括((r r) n),这会导致死循环。

    【讨论】:

    • 您能否建议如何让我的ifthenelse 像往常一样工作if
    • Lisp 语言的求值规则并不完全等同于 lambda 演算的 Beta 缩减规则,因此据我所知,您尝试做的事情是不可能的。
    • 万岁!能够使用方案的惰性评估功能来做到这一点。
    • 太棒了!发布为您自己问题的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    • 2011-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多