{-# LANGUAGE TemplateHaskell, KindSignatures, ViewPatterns, EmptyDataDecls #-} {- | Module : Data.Proxy.TH Copyright : (c) The University of Kansas 2011 License : BSD3 Maintainer : nicolas.frisby@gmail.com Stability : experimental Portability : see LANGUAGE pragmas (... GHC) Quasiquoter and TH-splice generator for proxies using @type-spine@'s @k -> *@ kind wrappers. -} module Data.Proxy.TH (module Data.Proxy.TH, Proxy(..)) where import Data.Proxy.TH.Aux import Type.Spine.Stage0 (kTypeG) import Language.Haskell.TH import Language.Haskell.TH.Quote import Data.Proxy qProxy :: QuasiQuoter qProxy = QuasiQuoter (\s -> [| Proxy :: $(typ s) |]) pat typ (error "Data.Proxy.TH.qProxy Dec") where typ s = do (i, k) <- parseProxy_ s let holder = kTypeG k [t| Proxy ($holder $(return i)) |] pat s = viewP [| id :: $(typ s) -> $(typ s) |] (conP 'Proxy []) thProxyT :: Type -> Q Type thProxyT ty@(unAppT -> (ConT n, length -> k)) = do i <- reify n (drop k -> ks) <- case i of TyConI (DataD _ _ tvbs _ _) -> return $ map tvb_kind tvbs TyConI (NewtypeD _ _ tvbs _ _) -> return $ map tvb_kind tvbs PrimTyConI _ args _ -> return (replicate args StarK) _ -> thProxyT_fail $ Just n let holder = kTypeG $ foldr ArrowK StarK ks [t| Proxy ($holder $(return ty)) |] thProxyT _ = thProxyT_fail Nothing thProxy :: Type -> Q Exp thProxy ty = [| Proxy :: $(thProxyT ty) |]