'('(LIST)'NIL'NIL)应该是(hanoi('('(list)'()'())中的lambda表达式))

时间:2013-11-11 01:11:38

标签: lisp common-lisp towers-of-hanoi

我正在尝试实现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)))
 )

1 个答案:

答案 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为您提供了1quote只是一个符号,可以出现在其他列表中,因此'('(list)'()'())(quote ((quote (list)) (quote ()) (quote ())))相同,后者评估为列表((quote (list)) (quote ()) (quote ()))。由于()也可以写为nil(或NIL),因此最后一个与('(list) 'NIL 'NIL)相同。在Common Lisp中,函数调用看起来像

(function arg1 arg2 ...)

其中每个argi都是一个表单,而function是一个符号(例如listhanoicar)或列表,在哪种情况下,它必须是lambda表达式,例如(lambda (x) (+ x x))。所以,在你的行

(hanoi('('(list)'()'())))

我们有一个函数调用。 functionhanoiarg1('('(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))))) 中获取abc的权利:

abc