Haskell game loop with keyboard handler
There is a nice language extension in GHC called ViewPatterns. Together with LambdaCase that fature allows you to shorten your code, I think. And do notation will be much more readable for imperative part.

runGameLoop game panel | victory game = return Victory
                       | otherwise = continue
    where
      anyEvent = gatPanelWindow panel &gt;&gt;= flip getEvent (Just 1)
      isRestart = (EventSpecialKey (KeyFunction 2) ==)
      isQuit = (EventSpecialKey (KeyFunction 10) ==)
      continue = do
          refreshGamePanel game panel
          render
          anyEvent &gt;&gt;= \case
              Just (isRestart -&gt; True) -&gt; return Restart
              Just (isQuit -&gt; True) -&gt; return Quit
              Just (EventSpecialKey (keyToDirection -&gt; Just dir)) -&gt;
                  runGameLoop (makeMove game dir) panel
              _ -&gt; runGameLoop game panel


Another variant is to consider using of Monad Maybe instance

runGameLoop game panel = nextStep where
    anyEvent = gatPanelWindow panel &gt;&gt;= flip getEvent (Just 1)
    nextStep = if victory game then return Victory else do
        refreshGamePanel game panel
        render
        liftM react anyEvent &gt;&gt;= \case
            Just continuation -&gt; continuation
            Nothing -&gt; runGameLoop game panel
    react event' = do
        event' &gt;&gt;= \case
            EventSpecialKey (KeyFunction 2) -&gt; return (return Restart)
            EventSpecialKey (KeyFunction 10) -&gt; return (return Quit)
            EventSpecialKey key -&gt; do
                dir &lt;- keyToDirection key
                return (runGameLoop (makeMove game dir) panel)
            _ -&gt; Nothing