在Clojure中重写Lisp之地的巫师游戏
我正试图改写《口齿不清的土地》中的巫师游戏 尝试时:在Clojure中重写Lisp之地的巫师游戏,clojure,jvm,lisp,land-of-lisp,Clojure,Jvm,Lisp,Land Of Lisp,我正试图改写《口齿不清的土地》中的巫师游戏 尝试时: (println (describe-paths :attic *edges*)) 我得到了一个例外: 线程“main”java.lang.RuntimeException中的异常:java.lang.IllegalArgumentException:不知道如何从clojure.lang.Symbol创建ISeq(wizard game.clj:0) 我的眼睛还不清楚,我做错了什么?将此放入REPL,然后运行跟踪: user>
(println (describe-paths :attic *edges*))
我得到了一个例外:
线程“main”java.lang.RuntimeException中的异常:java.lang.IllegalArgumentException:不知道如何从clojure.lang.Symbol创建ISeq(wizard game.clj:0)
我的眼睛还不清楚,我做错了什么?将此放入REPL,然后运行跟踪:
user> (ns foo (:use clojure.contrib.trace))
nil
此时,我将您的代码复制到REPL中。(未显示)
接下来,我运行一个跟踪:
foo> (dotrace [describe-location describe-path-raw describe-path describe-paths]
(describe-paths :attic *edges*))
TRACE t1662: (describe-paths :attic {:living-room ((garden west door) (attic upstairs ladder)), :garden (living-room east door), :attic (living-room downstairs ladder)})
TRACE t1663: | (describe-path-raw living-room)
; Evaluation aborted.
foo>
所以问题是(描述一下客厅)。正如错误消息所指出的,客厅是一个符号,这个函数试图对其执行“最后一次调用”和“第二次调用”之类的操作,而这只能在序列上完成
为什么会发生这种情况?
在描述路径中,您正在调用(位置边)。在这里,位置是:阁楼,边是地图。因此,(位置边缘)工程出(客厅楼下的梯子)。您正在将descripe path raw映射到此列表,其结果是:
((describe-path-raw living-room) (describe-path-raw downstairs) (describe-path-raw ladder))
这在第一次调用时引发了一个异常,因为客厅是一个符号,而不是一个序列。它看起来像
描述路径
期望在*edges*
映射中查找的值将是一个列表列表,而不仅仅是一个列表。请注意:客厅
条目与:花园
和:阁楼
条目之间的区别:前者有一个顶层脊椎,下面有两个三元组,而后两个只有一个三元组
函数descripe path raw
希望接收至少大小为2的元组,但它实际上只对大小为3的元组有意义;将*edges*
映射中的四个三元组中的任何一个馈送给它都会起作用。遇到的问题是由于将map
应用到*edges*
条目的:attic
,该条目将获取列表
(living-room downstairs ladder)
并将列表对象逐个馈送到描述原始路径:
(describe-path-raw living-room)
(describe-path-raw downstairs)
(describe-path-raw ladder)
在这三种形式中,传递给descripe path raw
的参数都是一个符号,而不是descripe path raw
所期望的列表
简言之,尝试在*edges*
地图的后两个值周围添加一组额外的括号,将每个列表嵌套在一个新的顶级列表中。为什么调用变为:(描述路径原始客厅)?:阁楼有列表类型的值。@4bu3li:请参阅我答案中的添加内容。我希望这有帮助。阁楼被映射到一个列表。我的意思是这是一份清单,对吗?”(客厅楼下的梯子)?我运行以下代码:(class(:attic)(客厅楼下的梯子)),它返回PersistentList。多亏了你和seh,我解决了这个问题,但我仍然没有找到真正的问题。@4bu3li:这是一个列表,对吗。它由描述路径函数内部的(位置边)返回。然后描述路径调用将描述路径原始映射到该列表。那有什么用?它将descripe path raw应用于该列表中的每个元素。该列表中的第一个元素是客厅,因此,用于求值的第一个函数调用(map descripe path raw living room)是(descripe path raw living room)。客厅是一种象征,而这并不是我们所需要的。
(describe-path-raw living-room)
(describe-path-raw downstairs)
(describe-path-raw ladder)