ghcjs-vdom-0.2.0.0: src/GHCJS/VDOM/Internal/TH.hs
{-# LANGUAGE CPP, TemplateHaskell, QuasiQuotes #-}
module GHCJS.VDOM.Internal.TH where
import Data.List (foldl')
import Language.Haskell.TH
import Unsafe.Coerce
mkTupleChildrenInstances :: Name -> Name -> Name -> Name -> Name -> [Int] -> Q [Dec]
mkTupleChildrenInstances cls method ty con wrapper xs =
concat <$> mapM (mkTupleChildrenInstance cls method ty con wrapper) xs
{-
instance cls (ty, ty, ...) where
method (con x1, con x2, ...) = wrapper (buildArrayIN x1 x2 ...)
{-# INLINE method #-}
-}
mkTupleChildrenInstance :: Name -> Name -> Name -> Name -> Name -> Int -> Q [Dec]
mkTupleChildrenInstance cls method ty con wrapper n = do
let xs = map (mkName.('x':).show) [1..n]
t = AppT (ConT cls) (iterate (`AppT` ConT ty) (TupleT n) !! n)
build = mkName ("GHCJS.Prim.Internal.Build.buildArrayI" ++ show n)
pat = [TupP (map (ConP con . (:[]) . VarP) xs)]
body = NormalB (AppE (ConE wrapper)
(foldl' (\e v -> AppE e (VarE v)) (VarE build) xs))
#if MIN_VERSION_template_haskell(2,11,0)
return [InstanceD Nothing [] t [ FunD method [Clause pat body []]
, PragmaD (InlineP method Inline FunLike AllPhases)
]
]
#else
return [InstanceD [] t [ FunD method [Clause pat body []]
, PragmaD (InlineP method Inline FunLike AllPhases)
]
]
#endif
mkTupleAttrInstances :: Name -> Name -> Name -> Name -> Name -> [Int] -> Q [Dec]
mkTupleAttrInstances cls method ty con wrapper xs =
concat <$> mapM (mkTupleAttrInstance cls method ty con wrapper) xs
{-
instance cls (ty, ty, ...) where
method (con k1 v1, con k2 v2, ...) =
wrapper (buildObjectIN k1 k2 v1 v2 ...)
{-# INLINE method #-}
-}
mkTupleAttrInstance :: Name -> Name -> Name -> Name -> Name -> Int -> Q [Dec]
mkTupleAttrInstance cls method ty con wrapper n = do
let xs = map (\i -> let si = show i in [mkName ('k':si), mkName ('v':si)]) [1..n]
t = AppT (ConT cls) (iterate (`AppT` ConT ty) (TupleT n) !! n)
build = mkName ("GHCJS.Prim.Internal.Build.buildObjectI" ++ show n)
pat = [TupP (map (ConP con . map VarP) xs)]
app e k v = AppE (AppE e (AppE (VarE 'unsafeCoerce) (VarE k))) (VarE v)
body = NormalB (AppE (ConE wrapper)
(foldl' (\e [k,v] -> app e k v) (VarE build) xs))
#if MIN_VERSION_template_haskell(2,11,0)
return [InstanceD Nothing [] t [ FunD method [Clause pat body []]
, PragmaD (InlineP method Inline FunLike AllPhases)
]
]
#else
return [InstanceD [] t [ FunD method [Clause pat body []]
, PragmaD (InlineP method Inline FunLike AllPhases)
]
]
#endif