アットウィキロゴ
SDLの場合GetTicks関数を使って1000分の1秒単位でシステム時間を取得する事ができる。
これを使ってメインループを制御する。
ちなみに、delay関数は1000分の1秒間隔で待機する関数。
多分使わない・・・と思ったら使うかもしれない。
 module Main where
 import Graphics.UI.SDL.Time
 import Control.Monad
 
 main :: IO ()
 main = do
   replicateM_ 10 $ do
     getTicks >>= print
     delay 600 



8/18更新:
上のサンプルだとSDLをquitしてないのでgetTicksの値がアプリケーションを終えても増え続ける。
実際には、ゲーム終了時にquitする事で、リセットされるらしい。

メインループ内では、一定間隔で処理を実行しつつ、ユーザーからの入力を受けなくてはいけない。
入力を受けるためには、pollEvents関数を使うと良い。戻り値であるEvent型については http://hackage.haskell.org/packages/archive/SDL/0.6.3/doc/html/Graphics-UI-SDL-Events.html を参照。

一定間隔でgetTicksの値を出力しつつ、イベントを受け取ったらその内容も出力するサンプルを以下に示す。
これをベースに、簡単にメインループを記述できるような仕組みを作る事でおよそ問題無さそう。

もうちょっと内容まとめたらブログに書く。
 module Main where
 import Data.Word
 import Graphics.UI.SDL.Events
 import Graphics.UI.SDL as SDL
 
 --initしてsetVideoModeすればとりあえず画面が表示される
 --setVideoModeの戻り値はSurfaceとかいう構造体で
 --画面の情報なんかを保持しているらしい
 gameinit :: IO () 
 gameinit = do
      SDL.init [SDL.InitEverything]
      SDL.setVideoMode 640 480 32 [] >>= print
 
 --メインループ処理
 mainLoop :: Word32 -> IO ()
 mainLoop ago = do
   delay 1 --1000分の1ミリ秒待機、これ入れないとCPU使用率が大変な事になる
   ev <- pollEvent --待機せずイベントを取得、waitEventとかだと処理が継続できない
   printEvent ev
   --画面が閉じられたらメインループ終了、それ以外の場合は再帰呼び出し
   if ev == Quit then return () else printTicks >>= mainLoop
    where
     --イベントを出力
     printEvent :: Event -> IO ()
     printEvent NoEvent = return ()
     printEvent ev = print ev 
 
     --適当な間隔でgetTicksを出力
     printTicks :: IO Word32
     printTicks = do
       t <- getTicks
       if ago + 100 < t then print t >> return t else return ago
 
 -------------------------------------------------
 
 main :: IO ()
 main = gameinit >> getTicks >>= mainLoop >> SDL.quit


同日更新:

さらに詳しくブログに書いた。
http://d.hatena.ne.jp/its_out_of_tune/20120818/1345307698
最終更新:2012年08月19日 01:56