[Haskell-cafe] How to variables
robert dockins
robdockins at fastmail.fm
Mon Jul 18 15:06:03 EDT 2005
>>>I'm doing a 3D simulation. Now I need something like variables in
>>>imperative languages. My mainLoop check for new events and renders
>>>scene.
>>
>>
>>Then you want IORef.
>>http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data.IORef.html
>>
>>
>>
>>Consider, however, that this kind of construct can be done without
>>mutable variables. (warning, made-up code ahead)
>>
>>
>>main = loop 0 0 0 -- initial values
>> where loop loop_num xpos ypos =
>> do e <- pollEvent
>> let xpos' = <calculate new xpos>
>> ypos' = <calculate new ypos>
>> someActionInvolvingPosition xpos' ypos'
>> when breakCondition (return ())
>> loop (loop_num+1) xpos' ypos'
>>
>>
>
> I saw it. The problem is, I need an amount of 100*X of mutable variables
> to implement the system (camera position, rotation, aceleration, ...,
> position and deformetion infomations for every object, ..., renderer
> situations [like temprary fading and other efects], ... and more)
Then you probably want a big labeled record,
data ProgramState =
ProgramState { var1 :: IORef Int
, var2 :: IORef Int
, var3 :: IORef Int
, objects :: IORef [Object]
, etc ....}
with a big nasty init function that calls newIORef a bunch of times with
the initial values. Then you just pass around your ProgramState value.
initProgramState :: IO ProgramState
initProgramState =
do ref1 <- newIORef 0
ref2 <- newIORef 12345
ref3 <- newIORef 1111
.....
return ProgramState { var1 = ref1, var2 = ref2, var3 = ref3, ... }
main = ps <- initProgramState
mainLoop ps
This has the nice property that you can add new fields to your record
without having to change the signature of dozens of functions.
Of course, you can alternately just create a big labeled record of pure
values, and stick the whole thing in an IORef, or use recursive argument
passing trick and skip the IORefs altogether. I'm not sure I'm
competent to give a breakdown of the advantages and disadvantages of
each method, although I am personally inclined toward avoiding IORefs.
Some people may suggest that you to create top-level IORefs using
unsafePerformIO, but I don't recommend that for this situation.
More information about the Haskell-Cafe
mailing list