>>261
自分のゲームの今のコードは複雑で長く、何より汚いから晒すのは正直恥ずかしい。
だから晒すのは、手続きっぽくて嫌だなぁと思うエッセンスの部分だけね。

簡単に言えば、[タイトル画面シーン] や [オプション画面シーン] などシーン毎に関数を作ってる。
この関数は、戻り値として「次のシーン」を返すようになっていて、
シーン内でプレイヤーが行った行動などによって次のシーンを決定する。

newtype SceneProc = SP (Time -> GamePad -> (ScreenDesc, SceneProc))

titleScene :: GameData -> SceneProc
titleScene gd = SP $ \t gp ->
  let scr = makeScreenDesc -- 画面を構成する指示書を作る
  in case 時間やゲームパッドなどの状態 of
    オプション画面へ遷移するなら -> (scr, optionScene gd)
    とくに何もしていないなら -> (scr, titleScene gd)

optionScene, playScene, gameOverScene・・・ :: GameData -> SceneProc

mainLoop :: SceneProc -> SceneProc
mainLoop (SP scene) = do
  (t, gp) <- 現在時間とゲームパッドの状態
  let (scr, next) = scene t gp
  disp scr -- 画面表示
  mainLoop next

(実際は GameData 型の中で IORef を多用してる。その方が記述がスッキリするから)

で問題は、こういう作りだと、titleScene などの各シーン関数で、
やたら if や case of で場合分けする羽目になるということ。
A なら B、C なら D、A でかつ B なら E などの記述が並んで、
ハッキリ言って、関数型特有の宣言的な記述からはほど遠く見える。