Pau*_*rth 6 scheme continuations haskell functional-programming
我在C#中编写了一个小的Scheme解释器,并意识到我实现它的方式,很容易添加对正确延续的支持.
所以我添加了它们......但是想要"证明"我们添加它们的方式是正确的.
然而,我的Scheme解释器不支持"变异"状态 - 一切都是不可改变的.
因此编写单元测试来暴露"向上"延续非常容易:
AssertEqual(Eval("(call/cc (lambda (k) (+ 56 (k 3))))"), 3);
Run Code Online (Sandbox Code Playgroud)
但是,我还想写一个单元测试,证明如果继续"逃避",那么它仍然有效:
AssertEqual(Eval("(call/cc (lambda (k) k))", <some continuation>);
Run Code Online (Sandbox Code Playgroud)
但是,当然,上面只会测试"我得到了延续"......而不是它实际上是一个有效的延续.
然而,我能找到的所有例子总是最终使用"set!".证明逃脱的延续.
什么是最简单的Scheme示例,它展示了在不依赖突变的情况下对向后延续的适当支持?
向后延续任何使用没有变异吗?我开始怀疑自己是不是,因为你只能用它来再次执行完全相同的计算......如果没有副作用,这是没有意义的.这就是Haskell没有延续的原因吗?
我不知道这是否是最简单的,但这里是一个使用向后延续而没有任何调用set!或类似的例子:
(apply
(lambda (k i) (if (> i 5) i (k (list k (* 2 i)))))
(call/cc (lambda (k) (list k 1))))
Run Code Online (Sandbox Code Playgroud)
这应该评估为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))))
Run Code Online (Sandbox Code Playgroud)
计算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))
Run Code Online (Sandbox Code Playgroud)
(man,stackoverflow的语法突出显示在方案上大量失败.)