如何在进入void错误之前中断递归调用

时间:2012-05-06 07:02:02

标签: recursion if-statement scheme racket

(define l '(* - + 4))

(define (operator? x)
    (or (equal? '+ x) (equal? '- x) (equal? '* x) (equal? '/ x)))

(define (tokes list)
  (if (null? list)(write "empty")
  (if (operator? (car list))

       ((write "operator")
        (tokes (cdr list)))

      (write "other"))))

代码工作得很好直到(tokes(cdr list)))到达文件末尾。有人可以告诉我如何防止这种情况。我是Scheme的新手,所以如果这个问题很荒谬,我会原谅我。

1 个答案:

答案 0 :(得分:6)

您必须确保在每种情况下推进递归(除了基本情况,列表为null时)。在您的代码中,您没有对(write "other")案例进行递归调用。另外,当有几个条件要测试时,你应该使用cond,让我用一个例子来解释 - 而不是这个:

(if condition1
    exp1
    (if condition2
        exp2
        (if condition3
            exp3
            exp4)))

更好地写这个,更具可读性,还有一个额外的好处,你可以在每个条件之后编写多个表达式而不需要需要使用begin形式:

(cond (condition1 exp1) ; you can write additional expressions after exp1
      (condition2 exp2) ; you can write additional expressions after exp2
      (condition3 exp3) ; you can write additional expressions after exp3
      (else exp4))      ; you can write additional expressions after exp4

...这引导我进入下一点,请注意,如果需要多个表达式,则只能为if的每个分支编写一个表达式以if形式给出条件,然后您必须用begin包围它们,例如:

(if condition
    ; if the condition is true
    (begin  ; if more than one expression is needed 
      exp1  ; surround them with a begin
      exp2) 
    ; if the condition is false
    (begin  ; if more than one expression is needed 
      exp3  ; surround them with a begin
      exp4))

回到你的问题 - 这是一般的想法,填补空白:

(define (tokes list)
  (cond ((null? list)
         (write "empty"))
        ((operator? (car list))
         (write "operator")
         <???>)   ; advance on the recursion
        (else
         (write "other")
         <???>))) ; advance on the recursion