2016-01-10 2 views
0

Что не так с этим кодом?Функция функции funcall не может взять автомобиль lisp

(defun f (l) 
    (funcall #'(lambda (ff) 
       (cond 
        ((null l)nil) 
        ((listp (car l)) (append ff (f (cdr l)) (car ff))) 
        (t (list (car l))))) 
      (f (car l)))) 

Если я вхожу (F «((1 2 3))) он дает мне ошибку:

"Cannot take car of 1". 

Что случилось?

+2

Вы вызываете '(f (car l))' безоговорочно, и результат должен быть готов до применения лямбда. '(f (car l))' будет, конечно, делать то же самое, чтобы вы закончили с '(f (car (car (car (car (car .....))))))' до тех пор, пока аргументы не будут длиннее список, в котором вы получите сообщение об ошибке. – Sylwester

ответ

3

Подробнее о комментарии @Sylwester, пожалуйста, дайте более подробное объяснение.

Если вы пишете (f '((1 2 3)) то функция f называется, l обязан ((1 2 3)), и результатом является применение функции внутреннего (lambda (ff) (cond ...)) к значению (f (car l)).

Для выполнения этого приложения сначала (f (car l)) оценивается для получения значения, и так как l связан с ((1 2 3)), его car является (1 2 3).

Таким образом, f применяется к списку (1 2 3), который привязан к l в рекурсивном порядке. Эта оценка снова означает, что f должна применять внутреннюю функцию (lambda (ff) (cond ...)) к значению (f (car l)), то есть к (f 1).

Процесс reapeated, l связан этот раз 1, и снова f следует применять внутреннюю функцию (lambda (ff) (cond ...)) к значению (f (car l)), но, так как l теперь 1, функция пытается оценить (car 1), который производит найденную вами ошибку.

+0

И как я могу это решить? –

+0

Мне непонятно, какова цель функции. Что ты пытаешься сделать? В противном случае я не могу предложить никаких исправлений. – Renzo

+0

Я создал функцию labda ff, потому что для школы у меня было требование предложить решение для исходного кода, в котором f (автомобиль l) не будет вызываться рекурсивно (во второй ветви). Итак, для этого есть лямбда-функция. Называть это вместо вызова f (автомобиль l). –

Смежные вопросы