Domanda

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

È stato utile?

Soluzione

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 ()
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top