如何在通用Lisp中将函数递归地应用于所有子列表?

时间:2019-02-24 07:20:58

标签: list loops recursion lisp common-lisp

现在我有一个列表:

(+ x (- 4 9))

我首先需要将(-4 9)更改为(-(4。0)(9。0)) (请过多担心这部分)

(defun typecheck (A)
(cond
  ((numberp A)
   (cons A 0))
  ((equal A 'x)
   (cons 1 1))
  (t A)))

然后我需要减去(4。0)和(9。0)(仍然不是我的问题,我不想发布此函数,因为它太长了...

它变成

(+ x (-5 . 0))

现在这一次我将x更改为(1.1),因此列表变为(+(1.1)(-5。0)) 我最终将它们加在一起(最终结果是(-4。1))

我的主要问题是如何让Lisp知道我要在(-(4。0)(9 .0))之后首先计算它们?我的函数将直接转到(+(1.1。)((-4 .0)(9。0))并给我一个错误消息。

我的过程:

(defun check (A)
  (cond
   ((atom A)
    (let ((newA (typecheck A)))
      (calucalte A)))
   ((listp A)
    (mapcar #'check A))

但是该函数不会存储任何内容...而且我也不知道该怎么做:(任何人都可以给我一些帮助吗?谢谢

1 个答案:

答案 0 :(得分:2)

如果我正确理解了问题,则应该只编写一个递归函数来处理操作和数字/符号转换,例如:

(defun tcheck (expr)
  (cond
    ((numberp expr)
     (cons expr 0))
    ((eq expr 'x)
     (cons 1 1))
    ((listp expr)
     (cond
       ((eq (first expr) '+)
        (let ((a (tcheck (second expr)))
              (b (tcheck (third expr))))
          (cons (+ (car a) (car b))
                (+ (cdr a) (cdr b)))))
       ((eq (first expr) '-)
        (let ((a (tcheck (second expr)))
              (b (tcheck (third expr))))
          (cons (- (car a) (car b))
                (- (cdr a) (cdr b)))))
       (T
         (error "Unknown operation"))))
    (T expr)))

具有以上功能

(tcheck '(+ x (- 4 9)))

返回(-4 . 1)