Template Haskell (TH) でデータ定義
列挙型とその文字表現を、データで定義できる TH を書いた。
-- モジュールA defDataConstsType "T_Digit" (map (\x -> "T_" ++ [intToDigit x]) [0..10]) defShowType "T_Digit" (map (\x -> ("T_" ++ [intToDigit x], "'" ++ [intToDigit x] ++ "'")) [0..10])
このように書くと、下と同じ意味になる(はず)。
data T_Digit = T_0 | T_1 ... instance Show T_Digit where show T_0 = "'0'" show T_1 = "'1'" ...
TH のコード本体は利用する側と別モジュールに書かなくてはいけない(制限)。
-- モジュールB defDataConstsType :: String -> [String] -> Q [Dec] defDataConstsType name ns = return d where d = [DataD [] (mkName name) [] (map (\n -> NormalC (mkName n) []) ns) [mkName "Eq", mkName "Enum"]] defShowType :: String -> [(String, String)] -> Q [Dec] defShowType name ht = return d where d = [InstanceD [] (AppT (ConT (mkName "Show")) (ConT (mkName name))) [FunD (mkName "show") [Clause [VarP x] (NormalB (CaseE (VarE x) -- (map (\(n,s) -> Match (ConP (mkName n) []) (NormalB (LitE (StringL s))) []) ht))) []]]] where x = mkName "x"