I asked a question the other day about passing application state
around an OpenGL program and I've consulted RWH and the inter-web
extensively and I think I am on the right lines so far!
In my main program, I use Data.IORef like this:
gameState <- newIORef $ newGameState
and GameState contains all the stuff to do with the game model. Next
the confusing bit... to make myself learn things I typed out the
full type of the keyboardMouseCallback function:
myKeyMouse :: Key -> KeyState ->
Modifiers -> Position -> IO ()
and slotted it into the code like so:
keyboardMouseCallback $= Just myKeyMouse
In order to be able to pass the "IORef GameState" into the keyboard
handler I have to re-type my keyboardMouseCallback function like so:
myKeyMouse :: IORef GameState -> Key
-> KeyState -> Modifiers -> Position -> IO ()
and modify the assignment in main to this:
keyboardMouseCallback $= Just (myKeyMouse
gameState)
But I haven't really understood *why* that is the case. The
displayCallback is also similarly affected as it is now:
myDisplay :: IORef GameState -> IO ()
... displayCallback $= (myDisplay gameState)
and again I am not sure what magic is happening here to have made it
compile and work! My real source of confusion is over my apparent
victory over the type system in that I appear to have extended the
type signature (is that the correct term?) for both of the callbacks
be prepending "IORef GameState" to them and yet it all compiles and
works. Is "prepending" the key ? I feel a tingling of Eureka! organ
but I am not sure yet.
Explanations are welcome as I am sure there is something "important"
here that will really advance my understanding of the type system.
It smells like curry but I don't think... hang on... the keyboard
one is wrapped in the Maybe monad... therefore(?) the function I am
handing in can be *any* type so long as they actually match types!
Is that it then? I can smell partial application and curry now.
HELP!
Thanks,
Sean.