[Haskell-beginners] [Solved] Re: State Monads (and OpenGL)

Lyndon Maydwell maydwell at gmail.com
Mon Nov 8 11:19:40 EST 2010


The IORef method is the technique I used to solve this same problem,
but I'd be interested to see if there was a nice solution involving
the state monad.

On Mon, Nov 8, 2010 at 8:07 PM, Tom Hobbs <tvhobbs at googlemail.com> wrote:
> In case anyone else happens across this and wonders the same as me.  I
> got this working by using IORef.  Like so;
>
> main = do
>    world <- sequence (take (worldSize * worldSize) $ repeat rand)
>    worldM <- newIORef world
>    -- snip more code
>   displayCallback $= (display worldM)
>    idleCallback $= Just (evolveM worldM)
>    -- snip yet more code
>
> evolveM ior_world = do
>    world <- readIORef ior_world
>    let evolved = evolve world
>    writeIORef ior_world evolved
>    postRedisplay Nothing
>
> Here, every time the idleCallback is called the world is evolved.
> Since the displayCallback also has a reference (is that an acceptable
> term?) to (IORef world) it can draw the latest evolved world.
>
> On Fri, Nov 5, 2010 at 3:55 PM, Tom Hobbs <tvhobbs at googlemail.com> wrote:
>> Hi all,
>>
>> I have a program which implements Conway's Game Of Life.  It even has
>> an open GL UI which shockingly works.
>>
>> I've followed a tutorial
>> (http://blog.mikael.johanssons.org/archive/2006/09/opengl-programming-in-haskell-a-tutorial-part-2/)
>> which tells how to get the open GL to animate, and according to my
>> sysouts, that's working to.  The problem I have comes with the fact
>> that between every frame I want to evolve my world but I'm really
>> struggling working out how to get the state stuff working.
>>
>> Here's a snippet of my main function;
>>
>> main = do
>>        world <- sequence (take (worldSize * worldSize) $ repeat rand) --
>> randomly generate a square world
>>        -- code snipped out
>>        displayCallback $= (display position world)  -- display method which
>> is called on every frame redraw
>>        mainLoop
>>
>> Here, world is a [Int] and represents my cells.  The display function
>> as referenced by "displayCallback" is the function that is called back
>> to everytime the frame is redrawn.
>>
>> I also have another function which takes in a world, updates the state
>> of the cells and the evolved world, thus;
>>
>> evolve :: [Int] -> [Int]
>>
>> I've been reading through (a lot of) tutorials on the state monad but
>> I'm not any closer to working out how I make the call to display take
>> some kind of updated world.
>>
>> I've also got the following code;
>>
>> type World = State [Int]
>>
>> evolveS :: World [Int]
>> evolveS = do
>>              w <- get
>>              let w2 = evolve w
>>              put w2
>>              return w2
>>
>> Which I believe to be the correct code for wrapping my [Int] in the
>> state monad but now I have two problems;
>>
>> 1) I don't know if it's correct
>> 2) I don't know how to apply it, even if it is
>>
>> Can anyone offer any advice?
>>
>> Many thanks,
>>
>> Tom
>>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>


More information about the Beginners mailing list