Lisp列表中的常见元素

时间:2017-04-20 02:00:35

标签: runtime-error lisp

我们最近开始在课堂上学习Common Lisp。我正在尝试实现一个带有两个列表并输出其公共元素的函数。我们仅限于使用基本功能表格。

(defun myCommon(L1 L2)
(cond
    ((null L1) nil) ;;check if the first list is empty
    ((null L2) nil) ;;check if the second list is empty
    ((eq (car L1) (car L2)) ((car L1) (myCommon (cdr L1) L2))) 
    (t (myCommon (cdr L1) L2)) ;;if they are not the same, recurse myCommon with L1 as (cdr L1)
)

我的问题是我无法理解为什么它会导致类型错误(违规数据:(CAR L1))。就我能理解它而言,似乎期待一种函数类型。

  

错误:TYPE-ERROR:DATUM(CAR L1):预期类型功能   快速链接打开:do(si :: use-fast-links nil)用于调试   由COND发出信号。   TYPE-ERROR:DATUM(CAR L1):预期类型功能

     

在COND打破。

1 个答案:

答案 0 :(得分:0)

你的问题是由于在cond的第二个分支中,当关于两个car s相等的条件为真时计算的表达式是:{{1 }}。

这里有一个列表,其中包含两个元素((car L1) (myCommon (cdr L1) L2))),位于需要表单的位置(即具有((car L1) (myCommon...))结构的列表)。因此系统会发出错误,因为(function argument1 argument2 ...)不是函数。我想你想要做的是生成一个包含这两个参数的新列表,例如可以通过“consing”获取它们,就像在(car l1)中一样,这就是你的函数重写:

(cons (car L1) (myCommon...))

请注意,如果您在(defun myCommon(L1 L2) (cond ((null L1) nil) ;;check if the first list is empty ((null L2) nil) ;;check if the second list is empty ((eq (car L1) (car L2)) (cons (car L1) (myCommon (cdr L1) L2))) (t (myCommon (cdr L1) L2)))) ;;if they are not the same, recurse myCommon with L1 as (cdr L1) 上尝试此功能,则会发现答案为(mycommon '(1 2 3) '(1 2 3 4)而非(1)。这是因为您只“消耗”第一个参数(通过(1 2 3)重复出现)。因此,您需要在必要时更正“消耗”第二个参数的功能。