【发布时间】:2012-07-31 12:03:11
【问题描述】:
我想将 FRP(即反应香蕉 0.6.0.0)用于my project(GDB/MI 前端)。但是我在声明事件网络时遇到了麻烦。
有来自 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 对“当前”状态的假设有时是错误的。
我已经尝试解决这个问题一个多星期了,但我就是想不通。非常感谢任何帮助。
【问题讨论】:
-
您的最后一行似乎有一个悬空括号。
where f state' ....
标签: haskell reactive-programming frp reactive-banana