我正在尝试实现Towers of Hanoi。我还没有在递归调用之间打印任何内容,但我一直收到错误
'('(LIST)'NIL'NIL)应该是lambda表达式
我已经读到这种情况发生的原因是由于括号有问题,但我似乎无法找到我的问题。当我尝试调用pass-list
函数时,我认为它发生在hanoi
函数中。我的代码:
(defun pass-list(list)
(hanoi('('(list)'()'())))
)
(defun hanoi ('('(1) '(2) '(3)))
(hanoi '('(cdr 1) '(cons(car 1) 2) '(3)))
(hanoi '('(cons(car 3)1) '(2)'(cdr 3)))
)
答案 0 :(得分:2)
此代码有许多语法问题;整个地方都有错误的引号,看起来你正试图用数字作为变量,这是行不通的。您提到的特定错误消息的来源来自
(hanoi('('(list)'()'())))
首先,要了解'x
和'(a b c)
中的quote是表格(quote x)
和(quote (a b c))
以及(quote anything)
的简写是在不评估anything
的情况下获取anything
的语法。因此'(1 2 3)
为您提供了列表(1 2 3)
,'1
为您提供了1
。 quote
只是一个符号,可以出现在其他列表中,因此'('(list)'()'())
与(quote ((quote (list)) (quote ()) (quote ())))
相同,后者评估为列表((quote (list)) (quote ()) (quote ()))
。由于()
也可以写为nil
(或NIL
),因此最后一个与('(list) 'NIL 'NIL)
相同。在Common Lisp中,函数调用看起来像
(function arg1 arg2 ...)
其中每个argi
都是一个表单,而function
是一个符号(例如list
,hanoi
,car
)或列表,在哪种情况下,它必须是lambda
表达式,例如(lambda (x) (+ x x))
。所以,在你的行
(hanoi('('(list)'()'())))
我们有一个函数调用。 function
为hanoi
,arg1
为('('(list)'()'()))
。但是如何评估这个arg1
?嗯,这是一个列表,这意味着它是一个功能应用程序。什么是function
部分?这是
'('(list)'()'())
与
相同'('(list 'NIL 'NIL))
但正如我刚才所说,唯一可以是function
的列表是lambda
表达式。这显然不是lambda
表达式,因此您会收到您所看到的错误。
我无法确定,但看起来你的目标是以下内容。标有**
的行有点问题,因为你用一些参数调用hanoi
,当它返回时(如果它返回;在我看来,你似乎永远在这里case),你不做任何结果。它被忽略了,然后你进入第三行。
(defun pass-list(list)
(hanoi (list list) '() '()))
(defun hanoi (a b c)
(hanoi (rest a) (cons (first a) b) c) ; **
(hanoi (cons (first c) a) b (rest c)))
如果hanoi
应该将一个列表作为参数,并且该列表应该包含三个列表(我不知道为什么你这样做而不是{{1}我只考虑三个参数,但这是一个不同的问题,它很容易修改;只需取一个参数hanoi
并从中提取第一,第二和第三个列表,并在递归调用上将单个列表传递给abc
:
hanoi
我实际上可能会在这里使用destructuring-bind
来简化从(defun hanoi (abc)
(let ((a (first abc))
(b (second abc))
(c (third abc)))
(hanoi (list (rest a) (cons (first a) b) c))
(hanoi (list (cons (first c) a) b (rest c)))))
中获取a
,b
和c
的权利:
abc