Search code examples
haskellstate-monadgtk2hs

State monad and gtk2hs


I am trying to retain some state on my GUI application so that I may be able to construct a list of values from user input. But I have trouble understanding the State monad so...
Here is some test code to illustrate what I want (it is obvious it will not compile, haven't even tryed to) :

-- // --

main :: IO ()
main = do
   initGUI
   build <- builderNew
   builderAddFromFile build "test.glade"

   mainWindow <- builderGetObject build castToWindow "mainWindow"
   mainWindow `onDestroy` mainQuit

   mQuit <- builderGetObject build castToButton "quit"
   mQuit `onClicked` mainQuit

   entry   <- builderGetObject build castToEntry "entry"
   mUpdate <- builderGetObject build castToButton "update"

   mUpdate `onClicked` do
      txt <- entryGetText entry
      runState (addToList txt) []
      return ()

   widgetShowAll mainWindow
   mainGUI

-- // --

addToList :: String -> State [String] ()
addToList ent = get >>= \x -> put $ x ++ [ent]

Anyway I think I should be using StateT instead of State but it is a complete mess in my head (have read so many tutos...). Even if it worked, it would not be good since I give an initial state of [] at each loop. The question is how do I write the function addToList so that each time the update button is pressed the user input is added to some state (a list of previous input)?


Solution

  • First of all, State is already StateT

    type State s = StateT s Identity
    

    Maybe you need to use StateT 1 level up, something like this:

    runStateT $
    put []
    lift $ mUpdate `onClicked` do
       txt <- lift $ entryGetText entry
       listWas <- get  
       put $ txt : listWas   --in reverse order
       return ()