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

Tom Hobbs tvhobbs at googlemail.com
Mon Nov 8 07:07:39 EST 2010


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
>


More information about the Beginners mailing list