首页 > 解决方案 > 嵌套分隔的延续转换

问题描述

我试图理解分隔的延续,我正在阅读这篇文章:

http://community.schemewiki.org/?composable-continuations-tutorial

我发现了这个重置/移位转换

 (reset (...A... (shift V E) ...B...)) 
 ; --> 
 (let ((V (lambda (x) (...A... x ...B...)))) 
   E)

例如,我尝试了这个表达式的转换(我认为append-map来自 Racket)

(reset (list (
(lambda (x) (* x x)) (shift k (append-map k '(1 2))) )))

得到了这个

(append-map 
(lambda (y) (list ((lambda (x) (* x x)) y))) '(1 2))

结果相同'(1 4)

我想知道是否可以将相同类型的转换(将消除重置/移位)应用于这样的表达式:

(reset (list (+ 
(shift k (append-map k '(1 2))) 
(shift k (append-map k '(3 4))) )))

以及结果将如何(它评估为'(4 5 5 6))。

标签: schemeracketcontinuationsdelimited-continuations

解决方案


看一下该页面上的脚注:

[2] 这种转换并不严格正确。实际上,在整个输出中放置了更多的复位。然而,这方面的细节超出了本介绍性文本的范围,只有在我们使用嵌套移位和重置时才有意义。

但是,为了完整起见,如果需要,这里是正确的转换:

 (reset (...A... (shift K E) ...B...)) 
 ; --> 
 (let ((K (lambda (x) (reset (...A... x ...B...))))) 
   (reset E)) 

 (reset E) 
 ; --> 
 E 

所以:

(reset (list (+ (shift k (append-map k '(1 2))) (shift k (append-map k '(3 4))))))

转换为:

(let ((k (lambda (x) (reset (list (+ x (shift k (append-map k '(3 4))))))))) 
  (reset (append-map k '(1 2))))

(reset (list (+ x (shift k (append-map k '(3 4))))))

又转换为:

(let ((c (lambda (y) (reset (list (+ x y)))))) 
  (reset (append-map c '(3 4)))) 

通过使用第二条规则删除reset,我们有:

(let ((k (lambda (x) (let ((c (lambda (y) (list (+ x y))))) 
                       (append-map c '(3 4))) ))) 
  (append-map k '(1 2)))

作为最终结果。


推荐阅读