Аргументы для применения в Лиспе - PullRequest
0 голосов
/ 13 января 2019

У меня возникла следующая проблема: при попытке использовать функцию APPLY с вызовом MAPCAR, лямбда-функция, переданная в APPLY, которая содержит только один параметр, список, возвращаемый MAPCAR, выдает следующую ошибку: *** - EVAL/APPLY: too many arguments given to :LAMBDA

Следующий код определяет, имеет ли гетерогенный список последний атом на любом уровне числового атома.

(DEFUN hasLastNumeric (L)
  (COND
   ((NUMBERP L) T)
   ((ATOM L) NIL)
   ((LISTP L)
    (APPLY #'(LAMBDA (Lst)
                     (COND ((EQ (LAST Lst) T) T)
                           (T NIL)))
           (MAPCAR 'hasLastNumeric L)))))

(WRITE (hasLastNumeric '(1 2 5)))

Ответы [ 2 ]

0 голосов
/ 13 января 2019

Если вы вызываете функцию, например. (#'(lambda (a b) (+ a b)) 2 3) существует требование, чтобы количество аргументов соответствовало количеству предоставленных аргументов. При использовании apply требования одинаковы, поэтому (apply #'(lambda (one) ...) lst) требует, чтобы lst был только одним списком элементов, таким как '(a), но это не может быть '() или '(a b). Единственный способ поддержать переменное количество аргументов, вам нужно использовать &rest аргументы, например. (apply #'(lambda (&rest lst) ...) '(a b))

Глядя на логику, я ее не понимаю. Вы хотите вернуть t, когда вы встретили список с последним элементом в виде числа, но также искали элементы списка в пути и возвращали рано, если вы их нашли. Это должно быть возможно без использования last на каждом шаге. например.

(defun has-a-last-numeric (lst)
  (labels ((helper (lst)
             (loop :for (e . rest) :on lst
                   :if (and (null rest) (numberp e))
                       :do (return-from has-a-last-numeric t)
                   :if (listp e)
                       :do (helper e))))
    (helper lst)))
0 голосов
/ 13 января 2019

Вам не нужно подать заявку. Зачем тебе это использовать? Помните: APPLY вызывает функцию и использует предоставленный список в качестве списка аргументов.

MAPCAR возвращает список.

(let ((foo (mapcar #'1+ '(1 2 3 4))))
   (cond ((eql (last foo) ...) ...)
       ...))

Проверьте также, что на самом деле last возвращает ...

...