Scheme 如何在方案中使用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")

目前,我正在学习Scheme语言。 我不知道如何在当前延续中使用call。(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)))))))))
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在递归过程中的用法的误解。