2011-03-19 195 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*地圖的後兩個值周圍添加一組額外的括號,將每個列表嵌套在新的頂層列表中。