[Haskell-cafe] Looking for a more functional way to do this

Jefferson Heard jefferson.r.heard at gmail.com
Wed Aug 6 14:27:47 EDT 2008


Adrian, my understanding is that it's not that simple, because I need
to preserve the state between calls to GLUT's callbacks, which all
return IO ().

2008/8/6 Adrian Neumann <aneumann at inf.fu-berlin.de>:
> There is the State Monad which is build just for that kind of purpose, I
> believe:
>
> http://www.haskell.org/all_about_monads/html/statemonad.html
>
> That would safe you from passing around the State
>
> Jefferson Heard schrieb:
>>
>> Working with HOpenGL and GLUT, I find myself approaching a common
>> problem with a common solution that I don't really like all that much,
>> as it reeks of procedural programming.  Basically the problem is that
>> of complex program state, such that when the user provides input to
>> the program in the form of a mouse click or a typed string or
>> character, the program updates its internal state to reflect this,
>> whether that's changing the rotation, scale, or position of a screen
>> element, or deciding what data to have loaded from disc.
>>
>> What I often do is something that looks like this:
>>
>> data ProgramState  = ProgramState {
>>    some_associative_data :: Map String String
>>  , position :: GL.Vector3 Float
>>  , look_at :: GL Vector3 Float
>>  , selectables :: Map GLuint NamedObject
>>  }
>>
>> render :: IORef ProgramState -> IO ()
>> render state = do
>>  st <- readIORef state
>>  ...
>>
>> handleMouseClicks :: IORef ProgramState -> GLUT.KeyboardMouseHandler
>> handleMouseClicks state ... = do
>>  st <- readIORef state
>>  ...
>>
>> main = do
>>  ...
>>  let st = ProgramState { Map.empty ... }
>>      render' = render st
>>      mouse' = handleMouseClicks st
>>
>>  GLUT.renderCallback $= render
>>  GLUT.keyboardMouseCallback $= Just mouse'
>>
>> and so on and so forth.   Generally there are not fewer than 5 and not
>> more than about 32 variables that I have to track between mouse
>> clicks, and there's all this boilerplate code as well.  I'm searching
>> for a better way to do this, and I feel sure there is one.  I'm
>> considering using Template Haskell or possibly SYB to generate this
>> code, but it also seems like I also ought to be able to declare some
>> kind of state monad or continuation monad that can encapsulate
>> ProgramState without having to declare an explicit structure for it
>> everytime.
>>
>> For one thing, I'd like to genericize this code and write something
>> akin to Processing for Haskell (http://www.processing.org).
>> _______________________________________________
>> Haskell-Cafe mailing list
>> Haskell-Cafe at haskell.org
>> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>



-- 
I try to take things like a crow; war and chaos don't always ruin a
picnic, they just mean you have to be careful what you swallow.

-- Jessica Edwards


More information about the Haskell-Cafe mailing list