1

編集:これは、削減または削減される機能の問題ではありませんでした。clojure.core/range関数をシャドーイングしました。

私には機能があります

(defn- roundfn [[xi ci bi oi :as state] r]
  (let [[xn cn bn] (newstate [xi ci bi] 0)
        exfn (word<-x xn)]
    [xn cn bn
     (into oi
           [(exfn [6 3 6 1])
            (exfn [4 1 4 7])
            (exfn [2 7 2 5])
            (exfn [0 5 0 3])])]))

ここで、x1、x2、および x4 はそれ自体がベクトルです。x3 は値です。

この関数を次のように減らすと

(reduce roundfn [[][] 0 []] (range 3))

また

(reduce roundfn [[][] 0 []] (vec (range 3)))

受け取っています IndexOutOfBoundsException clojure.lang.PersistentVector.arrayFor (PersistentVector.java:107)

この関数を次のように減らすと

(reduce roundfn [[][] 0 []] [0 1 2])

それは期待どおりに動作します

4

2 に答える 2

2

(このバージョンのソースの作業-- 質問のコメントに記載されているファイルの現在のリビジョンへのリンク。)

まず、コードを実行すると、リテラルのケースを含め、リストしたすべてのケースで REPL で例外が発生します[0 1 2]。これが事実でなかったとしたら、それは驚くべきことです。(注:rabbit-roundの代わりに を使用します。これroundfnは、GitHub のソースにある質問テキストで引用されている関数の名前だからです。)

問題のソースは次のとおりです (質問のコメントで指定された完全なソースへのリンクに基づく)。

  1. roundfn問題文に記載されている関数rabbit-roundがソースで呼び出されます。問題のコールは(reduce rabbit-round [[] [] 0 []] [0 1 2]).

  2. reducethan は初期引数を指定して呼び出しますrabbit-round。その中で への呼び出しroundfnが行われます (roundfn元のソースでは別の関数です): (roundfn [[] [] 0] 0). ここで例外がスローされます。

  3. roundfn2つの機能の構成です。すでに最初のものは問題の原因であることが判明しています:(update-counter-system [[] [] 0] 0)スロー.

  4. リダクション関数としてreduce使用する呼び出しがさらにあります。counter-system-round後者が最初に適用されたときに例外がスローされます: (counter-system-round [[] 0] 0).

  5. 見てみると、最初の行でcounter-system-round計算を試みていることがわかります。(nth c round)この時点で、は(空のベクトル) にcバインドされ、になります。したがって、この呼び出しは になり、正しくスローされます。[]round0(nth [] 0)IndexOutOfBoundsException

于 2013-06-10T22:19:47.687 に答える
0

私は自分の破壊でclojure.core\range関数を隠していました[lower upper :as range]

以下は動作しなかったバージョンです

(generate-keystream [_ {:keys [ss] :as initmap} [lower upper :as range]]
  (let [ns (conj ss [])]
    (reduce rabbit-round ns (range 3))))

以下は期待どおりに動作します ( の:as rng代わりにへの変更に注意してください:as range)

(generate-keystream [_ {:keys [ss] :as initmap} [lower upper :as rng]]
  (let [ns (conj ss [])]
    (reduce rabbit-round ns (range 3))))

これは理由(range 3)を説明し、(vec (range 3))両方とも機能しませんでしたが、機能[0 1 2]しました。最初の 2 つは、元のコードで評価さ([0 0] 3)れ、評価され、成功しました。(vec ([0 0] 3))[0 1 2][0 1 2]

学んだ教訓。関数をシャドウしない

補足として、これも機能します...

(generate-keystream [_ {:keys [ss] :as initmap} [lower upper :as range]]
  (let [ns (conj ss [])]
    (reduce rabbit-round ns (clojure.core/range 3))))
于 2013-06-10T22:29:14.130 に答える