如何应对Gtk2Hs应用程序状态(How to deal with application stat

2019-06-27 03:28发布

努力学习编写与Gtk2Hs我得到弥合事件驱动Gtk2HS和我的模型的持久状态之间的差距困难应用。 因此,为了简化,可以说,我有这个简单的应用程序

module Main where

import Graphics.UI.Gtk
import Control.Monad.State

main = do
    initGUI
    window <- windowNew
    button <- buttonNew
    set button [buttonLabel := "Press me"]
    containerAdd window button

    -- Events
    onDestroy window mainQuit
    onClicked button (putStrLn ---PUT MEANINGFUL CODE HERE---)

    widgetShowAll window
    mainGUI

和我的应用程序的状态是多少次的按钮被按下。 眼看其他职位喜欢这样 ,他们依靠MVars或IORefs这似乎并不令人满意给我,因为在将来也许我会想重构代码以使国家生活在自己的上下文。

我认为,解决方案应使用阶跃函数一样使用状态单子:

State $ \s -> ((),s+1)

但我不知道的含义,如何做到这一点在上面的代码或即使单子是我的问题的解决方案。

Answer 1:

有两种基本的方法:

  1. 使用某种类型的指针。 这是您的IORefMVar的做法。 您可以隐藏这一个背后MonadState如果你喜欢般的界面:

     newtype GtkT sma = GtkT { unGtkT :: ReaderT (IORef s) ma } deriving (Functor, Applicative, Monad, MonadIO) runGtkT = runReaderT . unGtkT instance MonadIO m => MonadState s (GtkT sm) where get = GtkT (ask >>= liftIO . readIORef) put s = GtkT (ask >>= liftIO . flip writeIORef s) 
  2. 拉一个“ 控制反转 ”式的把戏。 编写打印了一些回调,然后替换自己与新的回调,打印一个较大的数字。

如果您尝试使用StateStateT直接,你就要有一个坏的时间。



文章来源: How to deal with application state in Gtk2Hs