confusing bit... to make myself learn things I typed out the full type
of the keyboardMouseCallback function:
(you'll actually do this in production code too! It's a good habit.)
myKeyMouse :: Key -> KeyState -> Modifiers -> Position -> IO ()
and slotted it into the code like so:
keyboardMouseCallback $= Just myKeyMouse
Okay -- so here we're seeing that keyboardMouseCallback itself is an IORef:
keyboardMouseCallback :: IORef (Maybe (Key -> KeyState -> Modifiers ->
Position -> IO ()))
Keep in mind also:
($=) :: IORef a -> a -> IO ()
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)
Now let's look at the reason it works.
Your types are:
keyboardMouseCallback :: IORef (Maybe (Key -> KeyState -> Modifiers ->
Position -> IO ()))
myKeyMouse :: IORef GameState -> Key -> KeyState -> Modifiers ->
Position -> IO ()
Now, what's the type of the expression `myKeyMouse gameState'? Well,
you've assigned the first argument -- all functions are curried -- so
you get a partial application:
myKeyMouse gameState :: Key -> KeyState -> Modifiers -> Position -> IO ()
Now you wrap that in Just:
Just (myKeyMouse gameState) :: Maybe (Key -> KeyState -> Modifiers ->
Position -> IO ())
What was the type of keyboardMouseCallback again?
keyboardMouseCallback :: IORef (Maybe (Key -> KeyState -> Modifiers ->
Position -> IO ()))
So the partial application returns a function with the first argument
fixed -- and the resulting function's type is that which is used for the
callbacks.
HTH a little.
A