Scheme(DrRacket)-cond语句不适用于递归

Scheme(DrRacket)-cond语句不适用于递归,scheme,racket,Scheme,Racket,我正在使用drracketr5rs学习这个方案。我以为我已经确定了概念,但我无法让这个简单的递归练习起作用。我认为这是一个错误,但我不确定 有人能看到这个问题吗?希望能解释一下为什么我的代码不起作用?我真的很想学习这个函数式语言 此代码将正确生成#T和#F: (define three (lambda (L target1 target2 target3 sum) (cond ((= target1 0) (three L (car L) (cadr L) (caddr

我正在使用drracketr5rs学习这个方案。我以为我已经确定了概念,但我无法让这个简单的递归练习起作用。我认为这是一个错误,但我不确定

有人能看到这个问题吗?希望能解释一下为什么我的代码不起作用?我真的很想学习这个函数式语言

此代码将正确生成#T和#F:

(define three (lambda (L target1 target2 target3 sum)
    (cond
        ((= target1 0) (three L (car L) (cadr L) (caddr L) 0))
        ((NULL? L) (= (- sum (+ target1 (+ target2 target3))) (+ target1 (+ target2 target3))))  ; sum minus targets = targets
        (else (three (cdr L) target1 target2 target3 (+ sum (car L))))       ; return true if branch returns true
)))
当我用(3’(1 2 3 6)0 0 0 0启动程序时,它返回#T,因为1+2+3=6。当我用(3’(1 2 3 5)0 0 0 0 0)启动程序时,它会从1+2+3开始返回#F=五,

现在,问题来了。我想做多分支递归。但是,此代码每次都返回#T!因为我不能让它返回#F,所以我不能让它跳到递归的下一个分支

(define three (lambda (L target1 target2 target3 sum)
    (cond
        ((= target1 0) (three L (car L) (cadr L) (caddr L) 0))
        ((NULL? L) (= (- sum (+ target1 (+ target2 target3))) (+ target1 (+ target2 target3))))  ; sum minus targets = targets
        ((three (cdr L) target1 target2 target3 (+ sum (car L))) #T)       ; return true if branch returns true                  
        (else 'hit_the_bottom)  ; IT NEVER HITS THIS STATEMENT!                  
)))

有什么想法吗?

解决方案太复杂了,如果您只想检查列表中前三个数字的总和是否等于第四个数字,那么使用更简单的非递归方法会更好:

(define (three lst)
  (= (+ (first lst) (second lst) (third lst))
     (fourth lst)))
除此之外,你为什么不坚持第一种方法呢?它适用于您,但不清楚“多分支递归”是什么意思,为什么第二种方法需要它?第一种方法不是“多分支”吗?毕竟,它已经在两个部分递归调用
three
。关于第二种方法总是返回
#t
的原因,这一行:

(else 'hit_the_bottom)
((three (cdr L) target1 target2 target3 (+ sum (car L))) #t)
。。。将确实执行,但由于它是递归调用的一部分,因此将返回到此行:

(else 'hit_the_bottom)
((three (cdr L) target1 target2 target3 (+ sum (car L))) #t)
而到达底部的值
'hit_
#t
,因此整个过程最终将返回
#t
。请注意,在方案中,所有非
#f
的内容都是
#t
,尤其是在这种情况下,
'点击底部
将被解释为
#t
。为了明确
else
部分确实正在执行,运行此代码,您将看到
'点击屏幕底部
一次:

(define three
  (lambda (L target1 target2 target3 sum)
    (cond ((= target1 0)
           (three L (car L) (cadr L) (caddr L) 0))
          ((null? L)
           (= (- sum (+ target1 target2 target3))
              (+ target1 target2 target3)))
          ((three (cdr L) target1 target2 target3 (+ sum (car L)))
           #t)
          (else (display 'hit_the_bottom) 'hit_the_bottom))))

(three '(1 2 3 6) 0 0 0 0)
=> #t
(three '(1 2 3 5) 0 0 0 0)
=> hit_the_bottom #t

最后,要纠正第二种方法,将最后一行替换为
(else#f)
,它将按预期工作。

快速回答:将最后一行替换为
(else#f)
,它将工作。看看我下面的答案,你给了我一个更有效的选择。然后,你非常好地解释了我的问题,所以我现在完全明白为什么会发生。此外,您提供了一个修复程序,因此我的应用程序现在可以运行,我可以完成其他部分。你太棒了。非常感谢。