haskell - descargar - instalar gtk3 en windows
Cómo lidiar con el estado de la aplicación en Gtk2Hs (1)
Al tratar de aprender a escribir aplicaciones con Gtk2Hs, tengo dificultades para cerrar la brecha entre el evento guiado Gtk2HS y el estado persistente de mi modelo. Para simplificar, digamos que tengo esta sencilla aplicación
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
y el estado de mi aplicación es cuántas veces se presionó el botón. Al ver otras publicaciones como esta , confían en MVars o IORefs, que no me parecen satisfactorias, porque en el futuro tal vez quiera refactorizar el código para que el estado viva en su propio contexto.
Creo que la solución debería usar la mónada de estado usando una función de paso como:
State $ /s -> ((),s+1)
pero no estoy seguro de las implicaciones, cómo hacerlo en el código anterior o incluso si esa mónada es la solución correcta para mi problema.
Básicamente, hay dos enfoques:
Use un puntero de algún tipo. Este es su enfoque
IORef
oMVar
. Puede ocultar esto detrás de una interfaz similar aMonadState
si lo desea: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)
Tire un truco de estilo de " inversión de control ". Escriba una devolución de llamada que imprima un número, luego se reemplaza con una nueva devolución de llamada que imprime un número más alto.
Si intentas usar State
o StateT
directamente, StateT
un mal momento.