LISP不能拿T的CAR

时间:2017-09-11 22:36:20

标签: common-lisp

我正在尝试评估列表中的每个原子,看看它是否等于提供的数字,如果没有则删除,但我遇到了一个小问题。

我写了以下代码:

(defun equal1(V L)
     (cond((= (length L) 0))
          (T (cond( (not(= V (car(equal1 V (cdr L))))) (cdr L) )))
     )
)

(equal1 5 '(1 2 3 4 5))

我收到以下错误

Error: Cannot take CAR of T.

如果为动作添加(写“hello”),如果为true,则获得以下错误:

Error: Cannot take CAR of "hello".

我对LISP还很陌生,并且想知道到底发生了什么,我怎么能解决这个问题,这样我就可以正确地评估每个原子,如果没有原因则将其删除,因此CDr L就可以了。

2 个答案:

答案 0 :(得分:2)

carcdrcons类型对象的访问者。由于t"hello"不是cons,因此您会收到错误消息。

要修复它,您需要知道函数返回的类型而不是car,除非您知道它是cons

修改

首先关闭ident并清理代码..嵌套cond是不必要的,因为默认情况下cond if-elseif-else 结构:

(defun remove-number (number list)
  (cond ((= (length list) 0) 
         t)
        ((not (= number (car (remove-number number (cdr list))))) 
         (cdr list))))
        (t 
         nil)))

我希望您注意到我已经添加了在未提供结果时返回t的默认行为,因为我们知道=会返回t或{{1}所以在这种情况下长度为0时返回nil

我添加了默认情况,其中前两个谓词都不是真实的,并且默认返回t

我根据使用的功能命名了它。 nil只能用于数字参数,因此永远不会对符号,字符串等起作用。如果您追求的是相同的值,则需要使用=

现在看看这个我们可以看到函数返回值不是很容易推理。我们知道equaltnillist尾部的任何部分都是可能的,因此list可能不起作用,或者car它可能不会产生数字。

更好的方法是:

  1. 检查列表是否为空,然后返回(car nil)
  2. 检查第一个元素是否与nil具有相同的数值,然后递归列表的其余部分(跳过元素)
  3. 默认情况下应该使number列表中包含第一个元素,并将结果与​​列表的其余部分一起递归。
  4. 代码看起来像这样:

    cons

答案 1 :(得分:1)

您可以采取一些措施来改善此功能。

首先,让我们正确缩进

(defun equal1 (V L)
  (cond
    ((= (length L) 0))
    (T (cond
         ((not (= V (car (equal1 V (cdr L))))) (cdr L))))))

您可以使用(= (length l) 0),而不是(zerop (length l))。一个小的音节点。更糟糕的是,该分支没有返回任何价值。如果列表L为空,我们应该返回什么?

该功能的问题出在第一个T的{​​{1}}分支中。

我们想做的是

  1. 删除与cond
  2. 值相同的任何列表项
  3. 将任何非V的项目保留为=
  4. 该函数应返回一个列表。

    表达式

    V

    试图(我认为)处理条件1和2.但是它显然不起作用。

    我们必须记住,项目在列表中,同等功能的结果需要是一个列表。在上面的表达式中,函数的结果将是一个布尔值,因此函数调用的结果将是布尔值。

    该函数需要沿着列表的每个元素步进,当它看到匹配的值时,跳过它,否则使用cons函数来构建过滤的输出列表。

    这是一个帮助你的骨架。请注意,我们不需要嵌入式(cond ((not (= V (car (equal1 V (cdr L))))) (cdr L))) ,只需处理3个条件 - 列表为空,过滤掉值,或继续构建列表。

    cond

    当然,这是Common Lisp,有一个内置函数可以做到这一点。您可以查看(defun equal-2 (v l) (cond ((zerop (length L)) nil) ((= v (car l)) <something goes here>) ;skip or filter the value (t (cons (car l) <something goes here>)))) ;build the output list ...