0

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)?

Sarfraz
  • 225
  • 2
  • 10

1 Answers1

0

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 ()
wit
  • 1,612
  • 10
  • 10
  • I have one question, where do I define my initial state (here that would be a listWas value of [])? – Sarfraz Oct 07 '13 at 14:03
  • While your advice is dead on about using going some level higher it seems that for gtk2hs apps in general it might be better to use the Control.Concurent.MVar module. – Sarfraz Oct 11 '13 at 00:23