haskell - Scheme中没有显式突变的向后延续的最简单示例

标签 haskell functional-programming scheme continuations

我用 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/

相关文章:

haskell - 在 ghci 中指定 "load"操作的搜索路径

haskell - 如何根据运行时值创建有界实例?

Lisp 程序产生契约(Contract)违规

swift - 为什么我不能在 Swift 的 reduce 中正确地划分整数?

scala - 功能设计模式

list - 带列表的二叉搜索树

macros - 学习 Scheme 宏的资源 : define-syntax and syntax-rules

haskell - 条件中的意外分号

haskell - 生成任意范围内的最小限制

scala - 使用 State Monad 在 Scala 中进行功能广度优先搜索