Qt的QStateMachine的功能反应类似物

时间:2013-11-21 19:57:44

标签: haskell state-machine frp

QStateMachine框架提供了一种很好的声明方式来定义基于状态事件的应用程序。即然后发生一个事件,它执行一个回调(实际上它会触发一个信号但这还不够)并根据图形执行状态转换。

我对FRP没有任何实际经验,但通过浏览反应性香蕉的例子,我没有发现FRP是否可以解决类似的问题。例如,“两个计数器”示例处理状态为plain if accumB

那么有一种干净且声明性的融合FSA和FRP的方法吗?

1 个答案:

答案 0 :(得分:1)

请原谅我,如果我错过了关于FSA的观点,但我相信accumB和朋友可以很好地和声明地捕捉到你的目标。从本质上讲,个别状态是价值,而转变是功能。一个非常简单的例子可能从:

开始
data ToggleState = Off | On deriving (Show)

toggle :: ToggleState -> ToggleState
toggle Off = On
toggle On  = Off

emergencyShutdown :: ToggleState -> ToggleState
emergencyShutdown _ = Off

(目前我没有找到好的想法来捕捉QState()的“开放式枚举”式的schtick,虽然我认为这并不是什么大问题,因为他们偏爱典型的Haskeller的强类型。)

然后,我们建立了FRP网络,将状态捕获为行为(即时变值)并将事件转换为事件:

-- Assuming eFlipSwitch and ePushShutdownButton are
-- defined terms of user input; say, through
-- bindings to your favourite UI library.
let
    eToggle :: Event t (ToggleState -> ToggleState)
    eToggle = toggle <$ eFlipSwitch

    eShutdown :: Event t (ToggleState -> ToggleState)
    eShutdown = emergencyShutdown <$ ePushShutdownButton

    -- By defining the behavior, we state once and for all the
    -- temporal evolution of the state in terms of the transitions.
    bState :: Behavior t ToggleState
    bState = accumB Off $ eToggle `union` eShutdown

还有很多其他可能性。通过IO的事件可以触发reactimate次回调。如QStateMachine文档中所述,可以使用filterE和相关组合器完成防护。动画UI元素可以通过绑定模块轻松完成(在reactive-banana-wx中查找sink,或者就此而言,查找threepenny-gui)。等等。