如何在Racket中将带标记的提示与call / cc一起使用?

问题描述 投票:1回答:1

为什么输入此代码

(let ([cc #f]
      [pr (make-continuation-prompt-tag 'pr)])
  (call-with-continuation-prompt
   (λ () (displayln
          (+ 2 (call-with-current-continuation
                (λ (k) (set! cc k) 1)
                pr))))
   pr)
  (cc 4))

(在Racket v7.5上引发异常?:

3
; continuation application: no corresponding prompt in the current continuation
; Context:
;  /usr/share/racket/collects/racket/repl.rkt:11:26

虽然带有默认标签的相同代码按预期工作:

(let ([cc #f])
  (call-with-continuation-prompt
   (λ ()
     (displayln (+ 2 (call-with-current-continuation
                      (λ (k) (set! cc k) 1))))))
  (cc 4))
3
6

和相同的(与第一个代码片段相同)具有可延续的代码

(let ([cc #f]
      [pr (make-continuation-prompt-tag 'pr)])
  (call-with-continuation-prompt
   (λ () (displayln
          (+ 2 (call-with-composable-continuation
                (λ (k) (set! cc k) 1)
                pr))))
   pr)
  (cc 4))

也按预期工作:

3
6

第一个代码段出了什么问题?还是我的理解有什么问题?

scheme racket continuations
1个回答
2
投票

来自the docs for call-with-current-continuation

如果曾经使用proc的continuation参数,那么它将删除当前continuation的一部分,直到使用提示标记标记的最近提示(不包括提示;如果不存在这样的提示,则exn:fail:contract:引发连续异常),....

在您的第一个示例中,当您应用cc时,在上下文中(“在堆栈上”)没有提示pr发生应用程序时],因此会引发异常。

第二个示例有效,因为总是提示您输入默认标签。

第三个示例之所以有效,是因为call-with-composable-continuation创建的继续过程不会中止当前的继续,因此没有适用其先决条件的条件。 (这就是为什么它被认为是“可组合的”延续的一部分。)


如果有帮助,这是大约

如何根据call/ccabort-current-continuation定义call-with-compposable-continuation。 (警告:我没有测试过,因此可能存在错误。)在下面的类型注释中,我使用以下约定:P是与提示标记关联的结果类型,Acall/cccall/comp调用,这也是延续参数的类型。 是空类型;它实际上意味着“不回来”。
;; call-with-continuation-prompt : (-> P) PromptTag[P] -> P
;; Only allows default abort handler!

;; abort-current-continuation : PromptTag[P] (-> P) -> ⊥
;; Assumes the default abort handler!

;; call-with-composable-continuation : ((A -> P) -> A) PromptTag[P] -> A

;; call/cc : ((A -> ⊥) -> A) PromptTag[P] -> A
(define (call/cc proc tag)
  (call-with-composable-continuation
   (lambda (ck) ;; ck : A -> P
     ;; k : A -> ⊥
     (define (k v)
       (abort-current-continuation tag
         (lambda () (ck v))))
     (proc k))
   tag))

此定义不考虑call/ccdynamic-wind实际交互的方式,不适用于自定义提示处理程序,也不考虑多个返回值(对应于多个连续参数),但是它应该使您大致了解call/cc的功能。特别地,对abort-current-continuation的调用要求当前的延续具有标有tag的提示。

© www.soinside.com 2019 - 2024. All rights reserved.