6

この関数型リアクティブ プログラミングがどのように機能するかを理解しようとしていますが、問題が発生しました。私はboidシミュレーションを作成しようとしていますが、ゆっくりと始めています。今のところ、開始位置を取り、入力がポイントである位置から位置への信号関数を作成する関数としてboidを定義しましたに向かって移動しており、出力は現在の位置です。

type Position2 = Vector2 Float

boid :: Position2 -> SF Position2 Position2
boid s = loop (arr (uncurry seek) >>> integral >>> arr (^+^ s) >>> arr dup)

seek 関数は 2 つの入力を取ります (ループのため)。現在位置と目標位置。次に、現在の位置からターゲット位置に向かって 50 の大きさ、つまり速度で指すベクトルを作成します。次に、速度が積分され、開始位置が追加されます。最終的に、信号は 2 つに分割されるため、1 つが出力になり、もう 1 つがシーク関数にループバックされます。

これで、次のようにボイドを定義できます。

aBoid = constant (vector2 500 500) >>> (boid (vector2 600 60))
bBoid = aBoid >>> (boid (vector2 3 4))

ここで、aBoid は点 (500, 500) に向かってシークし、bBoid は aBoid に向かってシークします。

私の問題は、2つのボイドがお互いに向かってシークしたいときです。私がこれを行うとき:

aBoid = bBoid >>> (boid (vector2 600 60))
bBoid = aBoid >>> (boid (vector2 3 4))

プログラムは単に出力します:ProgramName: <<loop>>これは、無限ループに入ることを意味すると思います。

私はまた、次のような関数を使用しようとしましたpar:

sim :: SF a [Position2]
sim = loop (arr snd >>> par route [boid (vector2 10 10), boid (vector2 100 100)] >>> arr dup)

ここで、route関数は各boidの出力を別のboidの入力にマップするだけです( のようzipに、ただしオフセットは1です)

これも<<loop>>メッセージを与えます。

オブジェクトが互いの状態に依存することは、リアクティブ システムを扱う場合によくある問題だと思うので、洗練された解決策があることを願っています。

私は、この FRP のことは非常に難しく、しばしば混乱を招くと思うことを付け加えておきます。

4

2 に答える 2

3

私は Yampa/Animas にあまり詳しくありませんが、問題は基本的に、基本ケースのない再帰があることにあるようです。あなたはシステムの進化について説明しましたが、それがどのように始まったかについては説明していません。

どうですか:

aBoid = bBoid >>> boid (vector2 600 60) >>> iPre (vector2 0 0)
bBoid = aBoid >>> boid (vector2 3 4)

それaBoidは (0,0) から始まり、次の瞬間にフィードバック ループが始まりますか? iPreこれは、私の理解が正しいと仮定しています...

(.)(パイプラインは、 の反転バージョンである で想像すると理解しやすいかもしれません(>>>)。)

于 2011-12-27T22:02:04.583 に答える
2

それで、ehirdの少しの助けを借りて、私はうまくいく何かを思いついた。

コードは次のとおりです(ここでは2つではなく3つのボイドを使用しています)。

sim :: SF a [Position2]
sim = loopPre [zeroVector, zeroVector, zeroVector] (
    arr snd >>>
    par route [boid (vector2 10 10), boid (vector2 100 400), boid (vector2 500 500)] >>>
    arr dup)

ここで、ルート機能は、質問で説明したものと同じように機能します。

loopPreiの代わりに使用することでloop、各ボードに開始位置を与えることができ、問題が解決します。ehirdのソリューションが機能しなかった理由は、複数の信号関数を並列に実行するときに配管が必要であり、par関数がそれを処理するためだと思います。

何が起こっているのか100%確信している人からの回答をいただければ幸いです:)

編集

この実装simは少しきれいです:

sim :: Int -> SF a [Position2]
sim num = loopPre (take num (repeat zeroVector)) (
    arr snd >>>
    par route (randomBoids num) >>>
    arr dup)

ランダムなボイドrandomBoids numを生成する場所。num

于 2011-12-28T12:53:08.290 に答える