
On 4/30/07, Denis Volk
Hello all,
I am trying to make a (turn-based) game in Haskell and need to pass around quite a bit of information, so using the State monad seems most appropriate. My question is, which is a better idea:
1) Using State GameState r and then call execState for each game event (i.e. user input) so I can do IO 2) Using StateT GameState IO () and have the entire game live in one big execStateT call. (I note XMonad does something similar.)
There are difficulties with the first option, including keeping even more state about what we're doing (for instance, are we in a menu?), and adding stuff later would possibly require substantial rewrites. Other than the fact that I would have IO in places where it perhaps shouldn't be, the second option seems better, but I am new to all this and it may be that I'm missing something.
I like the second option better too. Also, you can make this type opaque (stick it in a newtype, use newtype deriving to derive the appropriate classes) and only export whatever IO actions you want to support (e.g. you may want to be able to spawn off a thread in a game for concurrent AI, so you could wrap that in a function that can only fork off Game actions, and not general IO actions, also you may want to be able to store certain game properties to disk for e.g. save games, but not allow general disk writes, so you only suply a savegame abstraction). You still get a nice encapsulation of what kind of IO actions people can do, because you don't have to allow them the use of "lift" or "liftIO". -- Sebastian Sylvan +44(0)7857-300802 UIN: 44640862