ton*_*ian 9 haskell gtk2hs state-monad
试图学习用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
Run Code Online (Sandbox Code Playgroud)
我的应用程序的状态是按下按钮的次数.看到像这样的其他帖子,他们依赖于MVars或IORefs,这对我来说似乎并不令人满意,因为将来也许我会想要重构代码,以便状态存在于自己的上下文中.
我认为解决方案应该使用状态monad使用步骤函数,如:
State $ \s -> ((),s+1)
Run Code Online (Sandbox Code Playgroud)
但我不确定其含义,如何在上面的代码中执行此操作,或者即使该monad是我的问题的正确解决方案.
基本上有两种方法:
使用某种指针.这是你IORef
或MVar
方法.MonadState
如果您愿意,可以将其隐藏在类似接口之后:
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)
Run Code Online (Sandbox Code Playgroud)拉出" 反转控制 "风格的伎俩.编写一个打印数字的回调,然后用一个打印更高数字的新回调替换自己.
如果您尝试使用State
或StateT
直接使用,您将度过一段美好时光.