我用C#编写一个小Scheme解释,并意识到,我已经实现了它的方式,这是很容易的添加适当延续支持。

所以我加入他们......但想“证明”自己的方式,我加他们是正确的。

我的Scheme解释却具有“突变”状态的支持 - 一切都是不可改变的。

因此,它是很容易编写一个单元测试,以暴露“向上”延续:

AssertEqual(Eval("(call/cc (lambda (k) (+ 56 (k 3))))"), 3);

不过,我也想写表明,如果继续“逃脱”,那么还是能够工作单元测试:

AssertEqual(Eval("(call/cc (lambda (k) k))", <some continuation>);

但当然,上述也只是测试“我得到了延续” ......不在于它实际上是一个有效的延续。

所有的例子我能找到,但最后总是使用“设置”!来演示转义延续。

什么是最简单的方案的例子,演示了向后延续适当的支持,而不依赖于基因突变?

是向下延续无突变有什么用处?我开始怀疑自己是不是,因为你只能用它来再次执行完全相同的计算......如果没有副作用,这是没有意义的。这是为什么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))

(曼,计算器的语法突出显示大量失败上的方案。)

其他提示

我想你是对的 - 没有突变,向后延续做任何转发延续不能

下面是我想出来的最好的:

AssertEqual(Eval("((call/cc (lambda (k) k)) (lambda (x) 5))", 5);

不惊人,但它是一个向后延续然后我“呼叫”与实际的函数I希望调用,返回数字5的功能。

AH和我也想出这个作为一个很好的单元测试用例:

AssertEqual(Eval("((call/cc call/cc) (lambda (x) 5))", 5);

我同意Jacob B制作 - 我不认为这是没有可变状态是有用的......但依然会感兴趣的一个反例。

<强>功能线程:

您可以用递归循环无突变更新状态。包括一个延续的状态被调用。现在,这是不是给其他的例子更复杂,但你真正需要的是thread-1main循环。其他线程和“更新”功能,在那里显示,延续可用于比一个简单的例子更多。此外,在这个例子中工作,你需要与指定让利的实现。这可以翻译成与限定语句所做的等效形式。

示例:

(let* ((update (lambda (data) data))                ;is identity to keep simple for example
       (thread-1                                    
         (lambda (cc)                               ;cc is the calling continuation
           (let loop ((cc cc)(state 0))
             (printf "--doing stuff       state:~A~N" state)
             (loop (call/cc cc)(+ state 1)))))      ;this is where the exit hapens
       (thread-2
         (lambda (data)                             ;returns the procedure to be used as 
           (lambda (cc)                             ;thread with data bound
             (let loop ((cc cc)(data data)(state 0))
               (printf "--doing other stuff state:~A~N" state)
               (loop (call/cc cc)(update data)(+ state 1)))))))
  (let main ((cur thread-1)(idle (thread-2 '()))(state 0))
    (printf "doing main stuff    state:~A~N" state)
    (if (< state 6)
        (main (call/cc idle) cur (+ state 1)))))

,其输出

doing main stuff    state:0
--doing other stuff state:0
doing main stuff    state:1
--doing stuff       state:0
doing main stuff    state:2
--doing other stuff state:1
doing main stuff    state:3
--doing stuff       state:1
doing main stuff    state:4
--doing other stuff state:2
doing main stuff    state:5
--doing stuff       state:2
doing main stuff    state:6
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top