プロジェクト(GDB / MIフロントエンド)にFRP(つまり、リアクティブバナナ0.6.0.0)を使用したいと思います。しかし、イベントネットワークを宣言するのに問題があります。
GUIからのコマンドと、GDBからの停止イベントがあります。両方を処理する必要があり、それらの処理はシステムの状態によって異なります。
私の現在のアプローチは次のようになります(これは問題を示すために必要な最小限の複雑さだと思います):
data Command = CommandA | CommandB
data Stopped = ReasonA | ReasonB
data State = State {stateExec :: Exec, stateFoo :: Int}
data StateExec = Running | Stopped
create_network :: NetworkDescription t (Command -> IO ())
create_network = do
(eCommand, fCommand) <- newEvent
(eStopped, fStopped) <- newEvent
(eStateUpdate, fStateUpdate) <- newEvent
gdb <- liftIO $ gdb_init fStopped
let
eState = accumE initialState eStateUpdate
bState = stepper initialState eState
reactimate $ (handleCommand gdb fStateUpdate <$> bState) <@> eCommand
reactimate $ (handleStopped gdb fStateUpdate <$> bState) <@> eStopped
return fCommand
handleCommand
handelStopped
現在の状態に応じて、コマンドに反応し、イベントを停止します。考えられる反応は、(同期)GDB I / O関数の呼び出しと、状態更新イベントの発生です。例えば:
handleCommand :: GDB -> ((State -> State) -> IO ()) -> State -> Command -> IO ()
handleCommand gdb fStateUpdate state CommandA = case stateExec state of
Running -> do
gdb_interrupt gdb
fStateUpdate f
where f state' = state' {stateFoo = 23}
問題は、f
によって評価されるときにaccumE
、state'
とは異なる場合があることですstate
。
時間と同時性の意味論と反応性バナナの「反応」の順序を完全に理解していないので、なぜこれが起こるのか100%確信が持てません。しかし、によって起動された状態更新関数は、状態を変更するhandleStopped
前に評価される可能性があると思います。f
f
とにかく、 「現在の」状態の仮定が時々間違っているので、このイベントネットワークは一貫性のない状態につながります。
私はこの問題を1週間以上解決しようとしてきましたが、理解できません。どんな助けでも大歓迎です。