【发布时间】:2018-06-09 15:52:08
【问题描述】:
在第 9 章的The Little Schemer book 中,在为任意长输入构建length 函数时,建议如下(在pages 170-171 上),在以下代码中 sn-p(来自page 168 本身) :
((lambda (mk-length)
(mk-length mk-length))
(lambda (mk-length)
((lambda (length)
(lambda (l)
(cond
((null? l) 0)
(else (add1 (length (cdr l)))))))
(mk-length mk-length))))
(mk-length mk-length) 部分将永远不会返回,并将无限地应用于自身:
因为我们只是一次又一次地将
mk-length应用到自身...
和
但是现在我们已经从生成
length的函数中提取了(mk-length mk-length),它不再返回一个函数。
现在,为了解决这个问题,本书建议:
在我们最后一个正确版本的
length中将mk-length的应用程序转换为一个函数。
喜欢,所以:
((lambda (mk-length)
(mk-length mk-length))
(lambda (mk-length)
((lambda (length)
(lambda (l)
(cond
((null? l) 0 )
(else
(add1 (length (cdr l)))))))
(lambda (x)
((mk-length mk-length) x)))))
让我不解的是:
-
如果
(mk-length mk-length)不返回函数
我们如何将
(mk-length mk-length)的结果应用到某个东西上,就好像它是一个函数一样?(lambda (x) ((mk-length mk-length) x)) -
将
(mk-length mk-length)包装到函数中如何解决“永不返回”(即无限递归)问题?我的理解是,在:(lambda (x) ((mk-length mk-length) x))
x 只会被传递给无限递归函数,它永远不会返回。
【问题讨论】:
-
不是无限递归。每个步骤都使用
(cdr l)作为参数,当它变为空时停止。 -
为什么你认为
(mk-length mk-length)不返回函数?mk-length的值是第二个 lambda 表达式,它返回(lambda (l) ...),这是一个函数。 -
参见。 Y combinator discussion in “The Little Schemer” 讨论了同一段代码。你的问题是already answered那里。
-
@DanD。虽然在那一点上仍然不是组合器,只是越来越接近它。当
(lambda (l) ...)被抽象掉时,它就变成了组合子。
标签: recursion scheme y-combinator the-little-schemer anonymous-recursion