目前,我正在学习Scheme语言。 我对如何使用call-with-current-continuation感到困惑。(call / cc) 为了更好地理解它,我为非本地出口编写了一个示例代码。 但它无法正常工作。
有谁知道为什么?任何帮助,将不胜感激。 提前致谢
[示例代码]
(define (product ls)
(call/cc
(lambda (return)
(cond
((null? ls ) =>
(begin
(display "list end")
(newline)
1)) ;; NG
;;(return 1)) ;; OK
((not (number? (car ls))) =>
(begin
(display "not number")
(newline)
(return 0)))
(else =>
(begin
(display (car ls))
(newline)
(* (car ls) (product (cdr ls)))))))))
[repl output]
gosh> (product '(1 2 a 3)) ; it works as I expected.
==> 1
==> 2
==> not number
==> 0 (return)
gosh> (product '(1 2 3)) ;; it doesn't work as I expected. I expect 6 as return value.
==> 1
==> 2
==> 3
==> list end
*** ERROR: invalid application: (1 #t)
答案 0 :(得分:4)
这里有几件事情。
首先,看起来您插入cond子句的=>
导致了问题。在Scheme中,=>
具有特殊含义......您不想要。拿出来,我想你会发现你的代码表现得像你期望的那样。
但是:你使用call / cc 而不是实际导致非本地退出,因为我相信你的意图。也就是说,我的猜测是你希望零点绕过所有等待的乘法,但事实并非如此。要看到这一点,请将0更改为无法乘以的字符 - 比如字符串"not a number"
- 并观察它失败。
这是因为您在每次调用函数时重新绑定return
。我想你可能真的想要这样的东西:
(define (product ls)
(call/cc
(lambda (return)
(letrec ([loop
(lambda (ls)
(cond
((null? ls )
(begin
(display "list end")
(newline)
1)) ;; NG
;;(return 1)) ;; OK
((not (number? (car ls)))
(begin
(display "not number")
(newline)
(return "not a number")))
(else
(begin
(display (car ls))
(newline)
(* (car ls) (loop (cdr ls)))))))])
(loop ls)))))
(product '(1 2 a 3))
...产生此输出:
1
2
not number
"not a number"
>