module Data.Tuple.Template where
import Control.Monad
import Language.Haskell.TH hiding ( tupleT )
tupleName :: Int -> Name
tupleName n = mkName $ "(" ++ replicate (n1) ',' ++ ")"
tupleT :: [TypeQ] -> TypeQ
tupleT args = appsT (conT (tupleName n)) args
where
appsT = foldl appT
n = length args
tupleE :: [ExpQ] -> ExpQ
tupleE args = appsE $ conE (tupleName n) : args
where n = length args
tupleP :: [PatQ] -> PatQ
tupleP ps = conP (tupleName n) ps
where n = length ps
decTupleCons :: Int -> Q Dec
decTupleCons n = do
aas@(a : as) <- replicateM n (varT <$> newName "a")
instanceD (cxt [])
(foldl appT (conT (mkName "TupleCons"))
[tupleT as])
[typeD aas, consInlD, consD, splitInlD, splitD]
where
typeD aas@(a : as) =
TySynInstD (mkName ":|") <$> tySynEqn [a, tupleT as] (tupleT aas)
consInlD = pragInlD (mkName "|:|") Inline FunLike AllPhases
splitInlD = pragInlD (mkName "split") Inline FunLike AllPhases
consD = do
xxs@(x : xs) <- replicateM n (newName "x")
funD (mkName "|:|")
[ clause
[ varP x, tupleP (varP <$> xs) ]
(normalB [| $(tupleE' xxs) |])
[] ]
splitD = do
xxs@(x : xs) <- replicateM n (newName "x")
funD (mkName "split")
[ clause
[ tupleP (varP <$> xxs) ]
(normalB [| ($(varE x), $(tupleE' xs)) |])
[] ]
tupleE' = tupleE . fmap varE