11

リアクティブバナナを学んでいます。ライブラリを理解するために、誰かがボタンを押すたびにカウンターを増加させるダミー アプリケーションを実装することにしました。

私が使用している UI ライブラリは Gtk ですが、説明には関係ありません。

これが私が思いついた非常に単純な実装です。

import Graphics.UI.Gtk
import Reactive.Banana
import Reactive.Banana.Frameworks

makeNetworkDescription addEvent = do
    eClick <- fromAddHandler addEvent
    reactimate $ (putStrLn . show) <$> (accumE 0 ((+1) <$ eClick))

main :: IO ()
main = do
    (addHandler, fireEvent) <- newAddHandler
    initGUI
    network <- compile $ makeNetworkDescription addHandler
    actuate network
    window <- windowNew
    button <- buttonNew
    set window [ containerBorderWidth := 10, containerChild := button ]
    set button [ buttonLabel := "Add One" ]
    onClicked button $ fireEvent ()
    onDestroy window mainQuit
    widgetShowAll window
    mainGUI

これは結果をシェルにダンプするだけです。Heinrich Apfelmusの記事を読んで、この解決策にたどり着きました。私の例では、単一の を使用していないことに注意してくださいBehavior

この記事には、ネットワークの例があります。

makeNetworkDescription addKeyEvent = do
    eKey <- fromAddHandler addKeyEvent
    let
        eOctaveChange = filterMapJust getOctaveChange eKey
        bOctave = accumB 3 (changeOctave <$> eOctaveChange)
        ePitch = filterMapJust (`lookup` charPitches) eKey
        bPitch = stepper PC ePitch
        bNote = Note <$> bOctave <*> bPitch
    eNoteChanged <- changes bNote
    reactimate' $ fmap (\n -> putStrLn ("Now playing " ++ show n))
               <$> eNoteChanged

この例は、stepperを に変換し、を使用してを戻すEventaを示しています。上記の例では、 のみを使用できましたが、違いはなかったと思います (私が何かを理解していない場合を除きます)。BehaviorEventchangesEvent

では、いつ、どのような理由で使用するのか、誰かが光を当てることができますBehaviorか? Eventすべての s をできるだけ早く変換する必要がありますか?

Behavior私の小さな実験では、どこで使用できるかわかりません。

ありがとう

4

3 に答える 3

7

Reactive Banana で FRP ネットワークが「何かをする」ときはいつでも、それは何らかの入力イベントに反応しているためです。そして、システムの外部で観測可能なことを行う唯一の方法は、外部システムを接続して、それが生成するイベントに反応するようにすることです ( を使用reactimate)。

したがって、出力イベントを生成して入力イベントに即座に反応するだけであれば、いいえ、を使用する理由はあまりありませんBehaviour

Behaviour複数のイベント ストリームに依存するプログラムの動作を生成する場合に非常に便利です。この場合、イベントが異なるタイミングで発生することを覚えておく必要があります。

Eventはオカレンスがあります。値を持つ特定の瞬間。ABehaviourはすべての時点で値を持ち、特別な瞬間はありません (ただしchanges、 は便利ですがモデルを壊すようなものです)。

多くの GUI でよく知られている簡単な例は、マウス クリックに反応し、Shift キーが押されていないときのクリックとは別のことを Shift-Click にさせたい場合です。Behaviourシフトキーが押されているかどうかを示す値を保持している場合、これは簡単です。Eventシフトキーのプレス/リリースとマウスクリックの s があった場合、それははるかに困難です。

難しいだけでなく、はるかに低レベルです。シフトクリックのような単純な概念を実装するためだけに、なぜ複雑な操作をしなければならないのでしょうか? との間の選択は、プログラムの概念を、プログラミングの世界の外で考える方法により密接に対応する用語で実装するのに役立つ抽象化です。BehaviourEvent

ここでの例は、ゲーム世界の可動オブジェクトです。移動するたびに表すことができます。Event PositionまたはBehaviour Position、常にそれがどこにあるかを表すこともできます。通常、私はオブジェクトが常に位置を持っBehaviourていると考えているので、より概念的に適合しています。

s が役立つもう 1 つの場所Behaviourは、プログラムが行うことができる外部観測を表す場合です。ここでは、「現在の」値のみを確認できます (変更が発生したときに外部システムが通知しないため)。

たとえば、プログラムで温度センサーを監視し、温度が高すぎるときにジョブを開始しないようにする必要があるとします。を使用するEvent Temperatureと、温度センサーをポーリングする頻度 (または何に応答して) を前もって決定する必要があります。そして、ジョブを開始するかどうかを決定するイベントで最後の温度測定値を利用できるようにするために手動で何かをしなければならないという、他の例と同じ問題があります。またはfromPoll、 を作成するために使用できますBehaviour Temperature。これで、温度の時変値を表す値が得られ、センサーのポーリングから完全に抽象化されました。Reactive Banana 自体が、センサーのポーリングを必要なだけ頻繁に処理します。そのためのロジックを差し挟む必要はまったくありません。

于 2014-11-07T23:32:27.643 に答える