alms-0.6.0: src/Meta/QuoteData.hs
---
--- My verson of Language.Haskell.TH.Quote
---
module Meta.QuoteData (dataToExpQ, dataToPatQ) where
import Language.Haskell.TH
import Data.Data
dataToQa :: forall a k q. Data a
=> (Name -> k)
-> (Lit -> Q q)
-> (k -> [Q q] -> Q q)
-> (forall b . Data b => b -> Maybe (Q q))
-> [(String, String)]
-> a
-> Q q
dataToQa mkCon mkLit appCon antiQ quals = loop where
loop :: forall b. Data b => b -> Q q
loop t =
case antiQ t of
Nothing ->
case () of
_ | Just str <- cast t -> mkLit (stringL str)
| otherwise ->
case constrRep constr of
AlgConstr _ ->
appCon con conArgs
IntConstr n ->
mkLit $ integerL n
FloatConstr n ->
mkLit $ rationalL (toRational n)
CharConstr c ->
mkLit $ charL c
where
constr :: Constr
constr = toConstr t
constrName :: Constr -> String
constrName k =
qual k $
case showConstr k of
name@('(':',':_) -> name
'(':name -> init name
name -> name
qual :: Constr -> String -> String
qual k =
let modname = tyconModule (dataTypeName (constrType k)) in
case lookup modname quals of
Nothing -> id
Just s -> ((s ++ ".") ++)
con :: k
con = mkCon (mkName (constrName constr))
conArgs :: [Q q]
conArgs = gmapQ loop t
Just y -> y
-- | 'dataToExpQ' converts a value to a 'Q Exp' representation of the same
-- value. It takes a function to handle type-specific cases.
dataToExpQ :: Data a
=> (forall b . Data b => b -> Maybe (Q Exp))
-> [(String, String)]
-> a
-> Q Exp
dataToExpQ = dataToQa conE litE (foldl appE)
-- | 'dataToPatQ' converts a value to a 'Q Pat' representation of the same
-- value. It takes a function to handle type-specific cases.
dataToPatQ :: Data a
=> (forall b . Data b => b -> Maybe (Q Pat))
-> [(String, String)]
-> a
-> Q Pat
dataToPatQ = dataToQa id litP conP