Haskellにはバイナリを読み書きする時に使えるBitSyntaxというライブラリがあります。rubyで言うところのpackとかunpackに近いでしょうか。パースする時には返り値の型が引数に依存するので、その部分のコードはTemplate Haskellになっています。例えば、tzfile形式のファイルをパースするならこんな感じになります。
{-# LANGUAGE TemplateHaskell #-} import Control.Exception import Control.Monad import Data.BitSyntax import qualified Data.ByteString as BS import qualified Data.ByteString.Char8 as BS8 import Data.Maybe import System.IO parseFile :: FilePath -> IO () parseFile path = do bracket (openFile path ReadMode) hClose (parse path) parse :: String -> Handle -> IO () parse name h = do header <- BS.hGet h 44 let Just (magic, ttisgmtcnt, ttisstdcnt, leapcnt, timecnt, typecnt, charcnt) = $(bitSyn ([Fixed 4, Skip 16] ++ replicate 6 (Unsigned 4))) header when (magic /= BS8.pack "TZif") $ fail "Invalid magic." transitionTimes <- forM [1..timecnt] $ \_ -> do liftM decodeU32 $ BS.hGet h 4 localTimeTypes <- forM [1..timecnt] $ \_ -> do liftM decodeU8 $ BS.hGet h 1 types <- forM [1..typecnt] $ \_ -> do b <- BS.hGet h 6 return $ fromJust $ $(bitSyn [Unsigned 4, Unsigned 1, Unsigned 1]) b abbrevs <- BS.hGet h (fromIntegral charcnt) leaps <- forM [1..leapcnt] $ \_ -> do b <- BS.hGet h 8 return $ fromJust $ $(bitSyn [Unsigned 4, Unsigned 4]) b isstds <- forM [1..ttisstdcnt] $ \_ -> do liftM decodeU8 $ BS.hGet h 1 isgmts <- forM [1..ttisgmtcnt] $ \_ -> do liftM decodeU8 $ BS.hGet h 1 return ()