状態を、コードで定義する動作と見なす必要がありますか?
ほとんどのシナリオでは、実際Behavior
に状態に s を使用する必要があります。GUI アプリケーションでは、インターフェイス イベントに応じて状態を更新したいことがよくあります。さらに、重要なことに、状態はイベントの発生間で存在し続けなければならState
ず、それは許可されません。より具体的には、 a の更新以外の何かを行うイベントの発生に対応する標準的な方法Behavior
は、次のreactimate
関数を使用することです。
reactimate :: Frameworks t => Event t (IO ()) -> Moment t ()
実行するアクションのタイプはIO ()
です。を使用して を使用して計算をrunStateT
実行することは可能ですが、計算は自己完結型であり、以前の状態を別の場所に渡すことはできません。この問題は、s を使用して、reactive-banana FRP インターフェイスを介してs を更新する場合には発生しません。s は、再度使用する必要があるまでそこに残ります。StateT s IO
reactimate
Event
Behavior
Behavior
状態が外部の「イベント」にも依存する場合、GUI に関連するだけでなく、IORef を検討する方がよいでしょうか?
必ずしも。多くの場合、やReactive.Banana.Frameworks
などのツールを使用して、外部 I/O アクションが発生したときに起動されるを作成できます。そうすれば、そのようなアクションをイベント ネットワークに統合できます。典型的な例の 1 つは timerです。reactive-banana には組み込みの時間の概念はありませんが、一定の間隔で発生する I/O アクションを通じてトリガーされる tick イベントを導入できます。fromAddHandler
newEvent
Event
とはいえ、場合によっては、まだ使用したい場合があります...
... IORef
s (または s などの他の種類の変更可能な変数MVar
)、何らかの理由でBehavior
s およびを使用してイベントに自由に反応する能力を制限するインターフェイスを備えたライブラリを使用する必要がある場合reactimate
。しばらく前に、このようなシナリオに関する非常に素晴らしい質問hArduino
がありました。そこにある 2 つの回答は、不利な状況で有用なイベント ネットワークを持つための異なる方法を示していますが、精神的には似ています。
...StateT
自己完結型のステートフル アルゴリズムがあり、その結果がイベント ネットワークの他の場所で使用されない場合は、それを実行して呼び出しrunStateT
に貼り付けることができます。reactimate
ばかげた例:次の行に沿ったIO ()
アクション:reactimate
displayMessageBox . show =<< evalStateT someStateComputation initialState