2011-03-19 122 views
9

我试图当试图从“Lisp的土地” http://landoflisp.com/wizards_game.lisp重写精灵游戏

(def *nodes* {:living-room "you are in the living-room. a wizard is snoring loudly on the couch." 
      :garden "you are in a beautiful garden. there is a well in front of you." 
      :attic "you are in the attic. there is a giant welding torch in the corner."}) 

(def *edges* {:living-room '((garden west door) (attic upstairs ladder)) 
      :garden '(living-room east door) 
      :attic '(living-room downstairs ladder)}) 

(defn describe-location [location nodes] 
    (nodes location)) 

(defn describe-path-raw [edge] 
    `(there is a ~(last edge) going ~(second edge) from here.)) 

(defn describe-path [edge] 
    (map #(symbol (name %)) (describe-path-raw edge))) 

(defn describe-paths [location edges] 
    (apply concat (map describe-path-raw (location edges)))) 

改写精灵游戏:

(println (describe-paths :attic *edges*)) 

我得到这个异常:

线程“main”中的异常java.lang.RuntimeException:java.lang.IllegalArgumentException:不知道如何从:cl创建ISeq ojure.lang.Symbol(wizard-game.clj:0)

我还没有Lispy眼,我做错了什么?

+0

+1“Lispy eye”。 – 2012-01-01 00:36:09

回答

8

把这个变成一个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> 

所以问题是(形容 - 路径 - 原起居室)。正如错误信息所指出的那样,客厅是一个象征,而这个功能正在试图做一些事情,比如最后一个和最后一个,这只能在序列上完成。

那么为什么会发生这种情况呢?

在describe-paths内部,您正在调用(位置边缘)。在这里,位置是:阁楼,边缘是地图。因此,(位置边缘)运行到(客厅楼下梯子)。如果您映射描述 - 路径 - 原料到这个列表,其中工程出来:

((describe-path-raw living-room) (describe-path-raw downstairs) (describe-path-raw ladder)) 

,这是扔在第一次调用一个例外,因为客厅是一个符号,而不是一个序列。

+0

为什么这个电话正在变得:(描述路径原始的客厅)? :阁楼有清单类型的价值。 – Chiron 2011-03-19 18:12:42

+0

@ 4bu3li:查看我的答案。我希望这有帮助。 – 2011-03-19 18:46:32

+0

阁楼被映射到一个列表。我的意思是这是一个列表,对吧? '(客厅楼梯)?我运行这个代码:(class(:attic'(living room room downstairs ladder))),它返回PersistentList。我解决了这个问题,谢谢你,但我仍然没有得到真正的问题。 – Chiron 2011-03-20 23:43:37

1

它看起来像describe-paths预计在*edges*映射中查找的值将是一个列表列表,而不仅仅是一个列表。请注意0​​条目和:garden:attic条目之间的区别:前者具有顶级主干,低于该顶级主干可以找到两个三元组,而后两个每个都只有一个三元组。

函数describe-path-raw预计会收到一个至少有两个大小的元组,但是对于大小为3的元组来说,它确实是唯一有意义的;喂它在*edges*地图中的四个三元组中的任何一个都可以工作。你跑进问题是由于应用map*edges*条目:attic,这需要在列表

(living-room downstairs ladder) 

和饲料对象列表一个接一个describe-path-raw

(describe-path-raw living-room) 
(describe-path-raw downstairs) 
(describe-path-raw ladder) 

在每在这三种形式中,传递给describe-path-raw的论点是一个符号,而不是describe-path-raw预计的名单。

简而言之,尝试在*edges*地图的后两个值周围添加一组额外的括号,将每个列表嵌套在新的顶层列表中。