9

"Land of 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*))

私はこの例外を得ました:

スレッド「メイン」の例外 java.lang.RuntimeException: java.lang.IllegalArgumentException: Do not know how to create ISeq from: clojure.lang.Symbol (wizard-game.clj:0)

私はまだ Lispy の目を持っていません。何が間違っているのでしょうか?

4

2 に答える 2

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-path-raw living-room) です。エラー メッセージが指摘するように、リビング ルームはシンボルであり、この関数は、最後と 2 番目の呼び出しなどを実行しようとしていますが、これはシーケンスでのみ実行できます。

では、なぜこれが起こっているのですか?

describe-path 内で、呼び出しています (ロケーション エッジ)。ここで、location は :attic で、edges は地図です。したがって、(ロケーション エッジ) は (リビングルーム 階下のはしご) になります。このリストに describe-path-raw をマッピングすると、次のようになります。

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

リビングルームはシーケンスではなくシンボルであるため、これは最初の呼び出しで例外をスローしています。

于 2011-03-19T17:16:09.067 に答える
1

マップで検索される値は、単なるリストではなく、リストのリストになることdescribe-pathsを期待しているようです。エントリとエントリの*edges*違いに注意してください。前者にはトップレベルのスパインがあり、その下に2つの3タプルがありますが、後者の2つにはそれぞれ1つの3タプルしかありません。:living-room:garden:attic

関数describe-path-rawは、少なくともサイズ2のタプルを受け取ることを期待していますが、実際には、サイズ3のタプルに対してのみ意味があります。*edges*マップ内の4つの3タプルのいずれかにフィードすると機能します。あなたが遭遇した問題は、リストを取得mapするの*edges*エントリに適用することによるものです:attic

(living-room downstairs ladder)

リストオブジェクトを1つずつdescribe-path-raw:にフィードします。

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

これらの3つの形式のそれぞれで、渡される引数describe-path-rawは、によって期待されるリストではなく、シンボルdescribe-path-rawです。

つまり、マップの2番目の2つの値の周りに括弧のセットを追加して、*edges*各リストを新しいトップレベルリスト内にネストしてみてください。

于 2011-03-19T21:06:19.497 に答える