递归检查列表中的原子

Bor*_*ort 5 recursion common-lisp

我试图编写一个小的递归程序来测试列表,并返回t,如果每个元素都是一个原子.我遇到的问题是,当函数收到一个空列表时,它返回t而不是所需的nil结果.我无法想出一种方法,让它为最初的空列表返回nil,并且仍然以递归方式正常运行.

(defun only-atoms (in)
  (if (null in)
    t
    (and (atom (first in)) (only-atoms (cdr in)) )
  )
)
Run Code Online (Sandbox Code Playgroud)

Ter*_*aug 2

该函数可以在不使用递归的情况下使用 eg 来实现every,如下所示:

(defun only-atoms (list)
  (and list (every #'atom list)))
Run Code Online (Sandbox Code Playgroud)

当涉及到您所说的问题时,函数返回T而不是NIL使用空列表调用函数时的所需结果:

  1. T如果为真,您的递归实现会显式返回(null in),这解释了您的发现。只需将其更改为所需的值即可NIL。考虑将if构造更改为and.

  2. 仅当列表包含多个项目时才进行递归调用。一个适当的测试就(rest in)可以了。如果列表位于最后一项,则提供真值而不是进行递归调用。

  3. 仔细定位调用only-atoms以确保函数可以尾递归。

例如:

    (defun only-atoms (list)
      (and list
          (atom (first list))
          (or (null (rest list))
              (only-atoms (rest list)))))
Run Code Online (Sandbox Code Playgroud)