1

この特定の機能が期待どおりに機能しない理由を理解しようとしています。エラー メッセージから、アキュムレータ用の空のベクトルを作成する方法に関係があると思われます。

2 要素ベクトルのシーケンスを返す単純な関数があります。

(defn zip-with-index
  "Returns a sequence in which each element is of the
   form [i c] where i is the index of the element and c
   is the element at that index."
   [coll]
   (map-indexed (fn [i c] [i c]) coll))

それはうまくいきます。別の関数で使用しようとすると問題が発生します

(defn indexes-satisfying
  "Returns a vector containing all indexes of coll that satisfy
   the predicate p."
  [p coll]
  (defn accum-if-satisfies [acc zipped]
    (let [idx (first zipped)
          elem (second zipped)]
      (if (p elem) 
        (conj acc idx)
        (acc))))
  (reduce accum-if-satisfies (vector) (zip-with-index coll)))

コンパイルはできますが、使用しようとするとエラーが発生します。

user=> (indexes-satisfying (partial > 3) [1 3 5 7])
ArityException Wrong number of args (0) passed to: PersistentVector
clojure.lang.AFn.throwArity (AFn.java:437)

ここで何が問題なのかわかりません。また、私がやろうとしていることをもっと 'Clojure 風に' 行う方法があれば、それについても聞きたいです。

4

3 に答える 3

2

より Clojure に似た方法については、次を使用できます。

(defn indexes-satisfying [pred coll]
  (filterv #(pred (nth coll %))
           (range (count coll))))

ベクトルではなくレイジー seq を返すには、filter代わりに使用します。filterv

defnまた、内部関数の定義には使用しないでください。代わりに、内部関数が定義されている名前空間でグローバル関数を定義し、それ以外に微妙な副作用があります。letfn代わりに使用してください:

(defn outer [& args]
  (letfn [(inner [& inner-args] ...)]
    (inner ...)))
于 2013-05-09T23:10:14.050 に答える
1

それを行うもう1つの方法は次のとおりです。

(defn indexes-satisfying [p coll]
  (keep-indexed #(if (p %2) % nil) coll))
于 2013-05-10T17:09:42.593 に答える