我用 C# 编写了一个小型 Scheme 解释器,并意识到我实现它的方式很容易添加对正确延续的支持。
所以我添加了它们......但想“证明”我添加它们的方式是正确的。
然而,我的 Scheme 解释器不支持“变异”状态——一切都是不可变的。
所以很容易编写一个单元测试来暴露“向上”的延续:
AssertEqual(Eval("(call/cc (lambda (k) (+ 56 (k 3))))"), 3);
但是,我还想编写一个单元测试来证明如果延续“转义”,那么它仍然有效:
AssertEqual(Eval("(call/cc (lambda (k) k))", <some continuation>);
但是,当然,上面只是测试“我得到了一个延续”……并不是说它实际上是一个有效的延续。
然而,我能找到的所有示例最终总是使用“set!”。来证明逃脱的延续。
什么是最简单的方案示例,它演示了在不依赖突变的情况下对向后延续的适当支持?
没有突变的向后延续有什么用吗?我开始怀疑它们不是,因为您只能使用它再次执行完全相同的计算……如果没有副作用,这将毫无意义。这就是 Haskell 没有延续的原因吗?
最佳答案
我不知道这是否是最简单的,但这里有一个使用向后延续而不调用 set!
的示例或类似的:
(apply
(lambda (k i) (if (> i 5) i (k (list k (* 2 i)))))
(call/cc (lambda (k) (list k 1))))
这应该评估为
8
.更有趣的是:
(apply
(lambda (k i n) (if (= i 0) n (k (list k (- i 1) (* i n)))))
(call/cc (lambda (k) (list k 6 1))))
计算
6!
(也就是说,它应该评估为 720
)。你甚至可以用
let*
做同样的事情:(let* ((ka (call/cc (lambda (k) `(,k 1)))) (k (car ka)) (a (cadr ka)))
(if (< a 5) (k `(,k ,(* 2 a))) a))
(伙计,stackoverflow 的语法突出显示在方案上大量失败。)
关于haskell - Scheme中没有显式突变的向后延续的最简单示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/983776/