tupleとlistを行き来する感じのやつ。
を作ってみました。だからどうしたという感じですが、GHCではタプルのサイズは62までですよ!!って感じで1つ。ごめんなさい。
module ListAndTuple where import Language.Haskell.TH import Th_Util import GHC.Base $(do return $ map makeLnT [2..62]) $(do return $ map makeTnL [2..62])
module Th_Util where import Language.Haskell.TH makeVarP str = VarP $ mkName str makeVarE str = VarE $ mkName str listPP :: [String] -> Pat listPP list = iter_listpp list where iter_listpp (s:"[]":[]) = InfixP (makeVarP s) (mkName "GHC.Base.:") (ConP (mkName "GHC.Base.[]") []) iter_listpp (s1:s2:[]) = InfixP (makeVarP s1) (mkName "GHC.Base.:") (makeVarP s2) iter_listpp (s1:s2:res) = InfixP (makeVarP s1) (mkName "GHC.Base.:") (iter_listpp (s2:res)) makeBody :: [String] -> Body makeBody list = NormalB (TupE (iter_makeVarE list)) where iter_makeVarE [] = [] iter_makeVarE (str:res) = [makeVarE str] ++ (iter_makeVarE res) makeLnT n = FunD (mkName ("l"++(show n)++"t")) [Clause [listPP makeP] (makeBody makeE) []] where makeE = map (\x -> "a"++(show x)) (take n $ iterate (+1) 1) makeP = (map (\x -> "a"++(show x)) (take n $ iterate (+1) 1)) ++ ["[]"] -- [FunD (mkName "t2l" [Clause [TupP [makeVarP "a1",makeVarP "a2]] (NormalB (ListE [makeVarE "a1",makeVarE "a2"])) []]] makeTnL n = FunD (mkName $ "t"++(show n)++"l") [Clause [TupP make_tupP] (NormalB (ListE make_listE)) []] where make_tupP = map (\x -> makeVarP x) (map (\x -> "a"++(show x)) [1..n]) make_listE = map (\x -> makeVarE x) (map (\x -> "a"++(show x)) [1..n])
module Main where import ListAndTuple main = print $ show $ t62l $ l62t (take 62 [1..])
どういう関数をコンパイル時に生成しているかと言いますと。
t2l (a1,a2) = [a1,a2] t3l (a1,a2,a3) = [a1,a2,a3] t4l (a1,a2,a3,a4) = [a1,a2,a3,a4] ... t62l (a1,a2,a3,a4,...,a62) = [a1,a2,a3,a4,....,a62] l2t (a1:a2:[]) = (a1,a2) l3t (a1:a2:a3:[]) = (a1,a2,a3) l4t (a1:a2:a3:a4:[]) = (a1,a2,a3,a4) ... l62t (a1:a2:a3:a4:...:a62:[]) = (a1,a1,a3,a4,...,a62)
まじこんな関数書くのぱねぇっスって時に使えるんじゃないッすかね。
何がしたいかっていうと
http://d.hatena.ne.jp/ranha/20080827/1219776931
この辺の記事のリストパターンマッチ関数を、全部勝手に作らせる事は出来るに違いないと。
ただ面倒くさいこと受けないなのでやりません。