You could declare an action as a function that transforms the world:
type Action = Word -> World
And then create actions for things independent of the keys to which you intend to bind them:
moveForward :: Action
moveForward world = ...
Then, you can pass a list of (key, action)
pairs to a doInput
function:
doInput :: [(CharKey, Action)] -> World -> IO World
doInput bindings world = foldM checkKey world bindings where
checkKey world (key, action) = do
pressed <- getKey key
return $ if pressed then action world else world
So in your main loop, you can do something like:
mainloop world = do
doRender world
world' <- doInput [(CharKey 'W', moveForward)] world
mainloop world'