1

再帰関数の呼び出しごとにいくつかのアイテムを作成し、すべてをリストに収集したいと考えています。つまり、私は次のようなことをしたいです:

(defn myfunc [x]
  (loop [x x retur '()]
    (when condition1
      (let [templist '()]
        (if condition2 (def templist (conj templist {:somekey someval})))
        (if condition3 (def templist (conj templist {:somekey someval})))
        (recur (+ x 1) (concat retur templist))))))

問題は、Clojure では let を再バインドできないことです。グローバル変数の使用は避けたいと思います。

4

3 に答える 3

3

コアの一部の関数は、同じシンボルをaにチェーンするこのパターンを使用して、let条件付きで値を作成します。contition1を永久ループしない例に変更し、whenをifに変更して、ループの最後に値を返すことができるようにする必要がありました。

(defn myfunc [x someval1 someval2 condition1 condition2 condition3]
  (loop [x x retur '()]
    (if (condition1 x)
      (let [templist '()
            templist (if condition2 (conj templist {:somekey1 someval1}) templist)
            templist (if condition3 (conj templist {:somekey2 someval2}) templist)]
        (recur (+ x 1) (concat retur templist)))
      retur)))

その後、テストすることができます:

 user> (myfunc 0 1 2 #(< % 5) true true)
 ({:somekey2 2} {:somekey1 1} {:somekey2 2} {:somekey1 1} {:somekey2 2} 
  {:somekey1 1} {:somekey2 2} {:somekey1 1} {:somekey2 2} {:somekey1 1})

user> (myfunc 0 1 2 #(< % 5) true false)
({:somekey1 1} {:somekey1 1} {:somekey1 1} {:somekey1 1} {:somekey1 1})

letの考え方は、条件がtrueの場合は各ステージで値を変更し、条件がfalseの場合は変更せずに値を返すことです。このパターンは、関数型コードに命令型の外観を与え、値がどのように構築されるかを明確にするのに役立ちますが、命令型ロジックを関数型プログラムに「変換」するためにそれを使用することもできます。

于 2013-01-31T01:04:30.610 に答える
1

->ステップ指向の操作を行う必要があるときはいつでも、スレッド化マクロを使用することを好みます。

(defn myfunc [x]
  (loop [x x retur '()]
    (when condition1
        (let [r (-> '()
                    (#(if condition2 (conj % {:somekey 1}) %))
                    (#(if condition3 (conj % {:somekey 2}) %)))]
        (recur (+ x 1) (concat retur r))))))
于 2013-01-31T05:12:18.007 に答える
0

一連の割り当てによって結果を取得している命令型パターンを使用しようとします。これの代わりに、関数型言語としてのclojureにとってより慣用的な、より宣言的な方法で問題を解決しようとすることができます。例えば

(defn myfunc [x]
  (loop [x x retur '()]
    (if condition1
      (recur (inc x) (concat retur
                             (when condition2 [{:somekey1 someval1}])
                             (when condition3 [{:somekey2 someval2}])))
      retur)))
于 2013-01-31T00:50:13.843 に答える