[英]Can the function argument to `call/cc` equivalently either invoke the continuation or return without invoking the continuation?
方案編程語言說
Scheme允許使用過程
call/cc
捕獲任何表達式的延續。 必須為call/cc
傳遞一個參數為p
的過程。call/cc
構造當前延續的具體表示並將其傳遞給p
。 連續本身由過程k
。 每次將k
應用於值時,它將值返回到call/cc
應用程序的繼續。 從本質上講,該值成為call/cc
應用程序的值。 如果p
不調用k
而返回,則該過程返回的值將成為call/cc
應用程序的值。
就用call/cc
而言,以下兩種定義p
等價的方式是:
p
返回而不調用k
, p
用其否則返回值調用k
? 我不確定如何定義call/cc
。 請問call/cc
曾經直接調用延續k
,除了通過間接p
調用k
?
call/cc
和p
都不調用延續k
很好嗎?
是, (call/cc (lambda (k) 1)) <=> (call/cc (lambda (k) (k 1)))
。 您可以通過使用延續傳遞樣式轉換來證明這一點。
關鍵部分是call/cc
的CPS形式為(lambda (k) (lambda (f) ((fk) k)))
。 這兩個函數的CPS形式為(lambda (c) (lambda (k) (c 1)))
和(lambda (c) (lambda (k) (k 1)))
。 代入和簡化,兩者都導致(lambda (k) (k 1))
。
我非常喜歡定界延續,因為它們具有:
(reset (1 + (shift (lambda (f) f)))) <=> (lambda (v) (+ 1 v))
這也可以通過代數證明。
要解決后續問題的詳細信息,我們可以使用來自http://matt.might.net/articles/cps-conversion/的代碼scheme-cps-convert.rkt
> (T-c '(call/cc (λ (k) 1)) 'halt)
'((λ (f cc) (f (λ (x _) (cc x)) cc)) (λ (k $k2873) ($k2873 1)) halt)
> (T-c '(call/cc (λ (k) (k 1))) 'halt)
'((λ (f cc) (f (λ (x _) (cc x)) cc)) (λ (k $k2940) (k 1 $k2940)) halt)
簡化第一個表達式:
((λ (f cc) (f (λ (x _) (cc x)) cc)) (λ (k $k2873) ($k2873 1)) halt)
= ((λ (k $k2873) ($k2873 1)) (λ (x _) (halt x)) halt)
= (halt 1)
第二個
((λ (f cc) (f (λ (x _) (cc x)) cc)) (λ (k $k2940) (k 1 $k2940)) halt)
= ((λ (k $k2940) (k 1 $k2940)) (λ (x _) (halt x)) halt)
= ((λ (x _) (halt x)) 1 halt)
= (halt 1)
證明它們相等,因此在該位置使用k或不使用k都沒有區別。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.