Scheme 如何在方案中使用call/cc进行非本地退出
目前,我正在学习Scheme语言。 我不知道如何在当前延续中使用call。(call/cc) 为了更好地理解它,我为非本地出口编写了一个示例代码。 但它不能正常工作 有人知道为什么吗?任何帮助都将不胜感激。 提前谢谢 [示例代码]Scheme 如何在方案中使用call/cc进行非本地退出,scheme,Scheme,目前,我正在学习Scheme语言。 我不知道如何在当前延续中使用call。(call/cc) 为了更好地理解它,我为非本地出口编写了一个示例代码。 但它不能正常工作 有人知道为什么吗?任何帮助都将不胜感激。 提前谢谢 [示例代码] (define (product ls) (call/cc (lambda (return) (cond ((null? ls ) => (begin (display "list end")
(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)))))))))
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)
[repl输出]
(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)))))))))
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)
这里发生了几件事 首先也是最重要的一点,您插入到cond子句中的
=>
似乎是导致问题的原因。在Scheme中,=>
具有特殊的含义。。。你不想要的。把它们去掉,我想你会看到你的代码的行为和你期望的一样
但是:您使用call/cc实际上并没有导致非本地退出,我相信您是有意的。也就是说,我的猜测是你想让零绕过所有等待的乘数,但事实并非如此。要看到这一点,请将0更改为不能相乘的值,例如字符串“nota 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"
>
这里发生了几件事 首先也是最重要的一点,您插入到cond子句中的
=>
似乎是导致问题的原因。在Scheme中,=>
具有特殊的含义。。。你不想要的。把它们去掉,我想你会看到你的代码的行为和你期望的一样
但是:您使用call/cc实际上并没有导致非本地退出,我相信您是有意的。也就是说,我的猜测是你想让零绕过所有等待的乘数,但事实并非如此。要看到这一点,请将0更改为不能相乘的值,例如字符串“nota 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"
>
谢谢你的建议。我根据你的评论修改了代码。最后,我意识到了示例代码中的缺陷。这是因为误解了“cond”语法和递归过程中call/cc的用法。谢谢您的建议。我根据你的评论修改了代码。最后,我意识到了示例代码中的缺陷。这是对“cond”语法和call/cc在递归过程中的用法的误解。