Предотвращение двойного вызова рекурсивной функции в Common Lisp - PullRequest
0 голосов
/ 12 февраля 2020

У меня есть эта функция Lisp:

(defun F(l)
      (cond
        ((atom l) -1)
        ((>(F(car l))0)(+(car l)(F(car l))(F(cdr l))))
        (t(F(cdr l)))
      )
)

и я хочу предотвратить двойной вызов рекурсивной функции (F (car l)) во второй строке cond с использованием лямбда-функции.

Я пытался что:

(defun F(l)
  ((LAMBDA (ff)
         (cond
             ((atom l) -1)
             ((> ff 0)(+(car l) ff (F(cdr l))))
             (t(F(cdr l)))
         )
    ) (F (car l)))
)

но я получаю ошибку:

АВТОМОБИЛЬ: 1 - это не список

при вызове (F '(1 2 3 4)).

Также я не уверен, правильно ли это позволяет избежать двойного рекурсивного вызова.

1 Ответ

4 голосов
/ 12 февраля 2020

Причина, по которой вы получаете эту ошибку, заключается в том, что вы звоните (car l) всегда , даже если l на самом деле не list.

. это нужно делать только тогда, когда необходимо :

(defun F(l)
  (if (atom l) -1
      (let* ((l1 (car l))
             (f1 (F l1))
             (f2 (F (cdr l))))
        (if (plusp f1)
            (+ l1 f1 f2)
            f2))))
...