7

私はちょうどこのコードを書いた:

(defn parameters [transform-factory state]
  (lazy-seq (let [[r1 state] (uniform state)
                  [r2 state] (uniform state)
                  [t state] (transform-factory state)]
              (cons [t [r1 r2]] (parameters transform-factory state)))))

(defn repeated-transform [mosaic n transform-factory state]
  (reduce transform-square mosaic
    (take n (parameters transform-factory state))))

このparameters関数は、 から生成された値の遅延シーケンスを生成しますstate。これは、何か (この場合は「モザイク」) の繰り返し変換をパラメーター化するために使用されます。

持ち歩かなければならないものがある場合(この場合はランダムな値を生成するため)にparameters現れる、かなり一般的なパターンを示しているように私には思えます。stateこれに名前はありますか?

最初の関数を書くためのより良い方法はありますか? 関連する問題は、状態を「運ぶ」 で解決できることがよくありますreduceが、ここでは削減するものは何もありません。同様に、reductions適合しないようです。これはモナドの良いケースですか?(理論的な観点から、複数のインスタンスを1つに結合する方法をどのように定義するかわかりませんが、おそらくそれは実際のアプリケーションを変更しません-モナドが他の場所で解決するような問題のように見えます。持ち運び可能)。

(ps乱数について言及しましたが、質問とは関係のない理由で、これを舞台裏で可変状態を使用するソリューションに置き換えることはできません-「通常の」ランダムルーチンが行うように)。

4

3 に答える 3

4

状態モナドを調べて、それが自分に適しているかどうかを確認できます。

モナドを使用するための一般的なガイドラインは次のとおりです。

  • 順次実行 (パイプライン操作)
  • 再利用可能なモジュール式の副作用処理 (例: エラー処理/ロギング/状態)
  • 純粋な関数でビジネス ロジックをクリーンに保つ

(Clojure で) 非常に役立つモナドに関するリソースは次のとおりです。

Adam Smyczek: モナドの紹介 (ビデオ) http://www.youtube.com/watch?v=ObR3qi4Guys

および Jim Duey: Clojure のモナド http://www.clojure.net/2012/02/02/Monads-in-Clojure/

于 2012-04-27T02:04:51.990 に答える
3

チェックインする必要があるのは->->>スレッドマクロです。

このようなコードの代わりに:

(let [state (dosomething state)
      state (dosomethingelse state)
      state (dolastthing state)]
    state)

あなたは書ける:

(-> state (dosomething) (dosomethingelse) (dolasttthing))

どの「スレッド」状態が関数を通過し、最終的にそれを返します。

さて、あなたのコードは私が書いたものに正確には従いません。私が想像する方法は、関数がハッシュマップを取得して返す場合でした。つまり、(均一状態)はを返す可能性があり{:state state-val :r1 r1-val}ます。

次に、次のようにコードを書き直すことができます。

(->> {:state state} (merge uniform) (merge uniform) (transform-factory))

ずっといい!:)

于 2012-05-02T22:10:13.110 に答える
3

[これが私がこれまでに見つけた最良の解決策であるため、自分自身に答えます]

上記を関数の折り返しとして書き直すことができます。したがって、関数はデータになり、状態は「パススルー」になり、使用される関数は各関数を状態に順番に適用し、結果を蓄積します。

これを実装するエレガントな方法がわかりません-折りたたまれた関数は「新しい」ように見え、状態とアキュムレータを追加/分離するには追加のボイラープレートが必要です-したがって、プロセス全体をfold-over. ソースはここにあり、使用中の関数の例はここにあります。

于 2012-04-29T20:30:05.677 に答える