Я понимаю, что это старая ветка, но она одна из первых, которая возникает, когда я гуглю сплющиваюсь. Решение, которое я обнаружил, похоже на рассмотренное выше, но форматирование немного отличается. Я объясню это так, как будто вы новичок в lisp, как я это делал, когда впервые гуглял этот вопрос, так что, вероятно, другие тоже будут.
(defun flatten (L)
"Converts a list to single level."
(if (null L)
nil
(if (atom (first L))
(cons (first L) (flatten (rest L)))
(append (flatten (first L)) (flatten (rest L))))))
Для новичков в lisp это краткое резюме.
Следующая строка объявляет функцию с именем flatten с аргументом L.
(defun flatten (L)
В строке ниже проверяется наличие пустого списка.
(if (null L)
Следующая строка возвращает nil, потому что cons ATOM nil объявляет список с одной записью (ATOM). Это базовый случай рекурсии и позволяет функции знать, когда остановиться. Строка после этого проверяет, является ли первый элемент в списке атомом, а не другим списком.
(if (atom (first L))
Затем, если это так, он использует рекурсию для создания плоского списка этого атома в сочетании с остальной частью плоского списка, который сгенерирует функция. cons объединяет атом с другим списком.
(cons (first L) (flatten (rest L)))
Если это не атом, то мы должны сгладить его, потому что это еще один список, который может иметь дополнительные списки внутри него.
(append (flatten (first L)) (flatten (rest L))))))
Функция добавления добавит первый список к началу второго списка.
Также обратите внимание, что каждый раз, когда вы используете функцию в lisp, вы должны заключать ее в скобки. Это смутило меня сначала.