Common lisp LISP不能乘T的车
我试图计算列表中的每个原子,看看它是否等于提供的数字,如果不等于,则删除它,但我遇到了一个小问题 我编写了以下代码:Common lisp LISP不能乘T的车,common-lisp,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. 如果我
(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。
car
和cdr
是cons
类型对象的访问器。由于t
和“hello”
不是cons
,因此会收到一条错误消息
要修复它,您需要知道函数返回的是什么类型,而不是car
,除非您知道它是cons
编辑
首先识别并清除代码。。嵌套的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
或nil
时,当长度为0时,它返回t
我添加了一个默认情况,其中前面的两个谓词都不是真的,它默认返回nil
我根据使用的函数给它命名=
只能用于数字参数,因此这对符号、字符串等不起作用。如果要查找相同的值,则需要使用equal
现在看看这个,我们可以看到函数返回值不是很容易推理的。我们知道t
、nil
和list
或list
尾部的任何部分都是可能的,因此执行car
可能不起作用,或者在(car nil)
的情况下,它可能不会产生一个数字
更好的方法是:
nil
number
具有相同的数值,然后与列表的其余部分一起递归(跳过该元素)cons
列表中的第一个元素和递归结果以及列表的其余部分(defun remove-number (number list)
(cond ((endp list) '())
((= (car list) number) (remove-number ...))
(t (cons ...))))
car
和cdr
是cons
类型对象的访问器。由于t
和“hello”
不是cons
,因此会收到一条错误消息
要修复它,您需要知道函数返回的是什么类型,而不是car
,除非您知道它是cons
编辑
首先识别并清除代码。。嵌套的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
或nil
时,当长度为0时,它返回t
我添加了一个默认情况,其中前面的两个谓词都不是真的,它默认返回nil
我根据使用的函数给它命名=
只能用于数字参数,因此这对符号、字符串等不起作用。如果要查找相同的值,则需要使用equal
现在看看这个,我们可以看到函数返回值不是很容易推理的。我们知道t
、nil
和list
或list
尾部的任何部分都是可能的,因此执行car
可能不起作用,或者在(car nil)
的情况下,它可能不会产生一个数字
更好的方法是:
nil
number
具有相同的数值,然后与列表的其余部分一起递归(跳过该元素)cons
列表中的第一个元素和递归结果以及列表的其余部分(defun remove-number (number list)
(cond ((endp list) '())
((= (car list) number) (remove-number ...))
(t (cons ...))))
您可以做一些事情来改进此功能 首先,让我们适当地缩进它
(defun equal1 (V L)
(cond
((= (length L) 0))
(T (cond
((not (= V (car (equal1 V (cdr L))))) (cdr L))))))
不要说(=(长度l)0)
,您可以使用(zerop(长度l))
。次要的三段论观点。更糟糕的是,分支不返回任何值。如果列表L
为空,我们应该返回什么
函数的问题出现在第一个cond
的T
分支中
我们想做的是
V
=
的项目保留到V
(cond
((not (= V (car (equal1 V (cdr L))))) (cdr L)))
他(我认为)正在尝试处理条件1和条件2。然而,它显然不起作用
我们必须记住,项目在一个列表中,相等函数的结果需要是一个列表。在上面的表达式中,函数的结果将是布尔值,因此函数调用的结果将是布尔值
该函数需要沿着列表中的每个元素单步执行,当它看到匹配的值时,跳过它,否则使用cons函数构建过滤后的输出列表
这里有一个骨架来帮助你。请注意,我们不需要嵌入的cond
,只需要处理3个条件-list empty、过滤一个值或继续构建列表
(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
(定义等于-2(v l)
(续)
((零p(长度L))零)
(=v(car l));跳过或过滤该值
(t(cons(car l));;建立输出