How to deal with application state in Gtk2Hs

你说的曾经没有我的故事 提交于 2019-11-27 16:24:40

问题


Trying to learn to write applications with Gtk2Hs I'm getting difficulties bridging the gap between the event driven Gtk2HS and the persistent state of my model. So to simplify, lets say that I have this simple application

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

and the state of my application is how many times the button has been pressed. Seeing other posts like this they rely on MVars or IORefs which do not seem satisfactory to me, because in the future maybe I will want to refactor the code so the state lives on its own context.

I think that the solution should use the State monad using a step function like:

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

but I'm not sure about the implications, how to do that in the above code or even if that monad is the right solution to my problem.


回答1:


There's basically two approaches:

  1. Use a pointer of some kind. This is your IORef or MVar approach. You can hide this behind a MonadState-like interface if you like:

    newtype GtkT s m a = GtkT { unGtkT :: ReaderT (IORef s) m a } deriving (Functor, Applicative, Monad, MonadIO)
    runGtkT = runReaderT . unGtkT
    
    instance MonadIO m => MonadState s (GtkT s m) where
        get   = GtkT (ask >>= liftIO . readIORef)
        put s = GtkT (ask >>= liftIO . flip writeIORef s)
    
  2. Pull an "inversion of control" style trick. Write a callback that prints a number, then replaces itself with a new callback that prints a higher number.

If you try to use State or StateT directly, you're gonna have a bad time.



来源:https://stackoverflow.com/questions/12002814/how-to-deal-with-application-state-in-gtk2hs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!