Scheme 程序不评估嵌套列表?

Scheme program not evaluating nested lists?

我正在编写一个方案程序,该程序评估最后带有运算符的列表。

示例:(计算'(1 2 +)) --> 3

我有适用于基本运算符(+、-、*、/)的函数,但是当我有嵌套列表时就会出现问题。

示例:(计算'(1 (2 3 +) *)) --> (无)

我是不是漏掉了一个条件?

    (define (evaluate lis)
     (cond
      ((not (list? lis))
        lis)
      ((list? lis)
        (if (equal? (length lis) 3)
          (cond
            ((equal? (cddr lis) '(+))
             (+ (car lis) (car (cdr lis))))
            ((equal? (cddr lis) '(-))
             (- (car lis) (car (cdr lis))))
            ((equal? (cddr lis) '(*))
             (* (car lis) (car (cdr lis))))
            ((equal? (cddr lis) '(/))
             (/ (car lis) (car (cdr lis)))))))))

您忘记了对子表达式递归调用过程。请参阅此处,为简洁起见,我将其重命名为 !

(define (! lis)
  (cond
    ((not (list? lis))
     lis)
    ((list? lis)
     (if (equal? (length lis) 3)
       (cond
         ((equal? (cddr lis) '(+))
          (+ (! (car lis)) (! (cadr lis))))
         ((equal? (cddr lis) '(-))
          (- (! (car lis)) (! (cadr lis))))
         ((equal? (cddr lis) '(*))
          (* (! (car lis)) (! (cadr lis))))
         ((equal? (cddr lis) '(/))
          (/ (! (car lis)) (! (cadr lis)))))))))

顺便说一句,您可以按照以下方式重写程序:

(define (evaluate lis)
  (cond
    ((not (list? lis)) lis)
    ((= (length lis) 3)
     (let ((op (case (caddr lis)
                 ((+) +)
                 ((-) -)
                 ((*) *)
                 ((/) /))))
       (op (evaluate (car lis)) (evaluate (cadr lis)))))))

我有 3 个建议:

如果其中一个参数是表达式,则您不会对其求值。因此。您还需要 运行 postfix 两个参数。

当长度不是 3 时,您让实现选择 if 应该 return 的值。对于球拍 #<void>。也许你应该选择一些东西?

因为你的单词有固定数量的参数,所以不需要括号:

(define (peval exprs)
  (define primitives `((+ . ,+) (- . ,-) (* . ,*) (/ . ,/)))
  (foldl (lambda (operator operands)
           (let ((aproc (assq operator primitives)))
             (if aproc
                 (cons ((cdr aproc) (cadr operands) (car operands))
                       (cddr operands))
                 (cons operator operands))))
         '()
         exprs))

(peval '(2 3 4 + *)) ; (2 (3 4 +) *) == 14

注意这里的参数实际上是自动求值的。这就是连接语言(又名堆栈语言)的工作方式。