The type must be available along with everything else in the Info value provided by reify . In particular, you should get a TyConI that contains a Dec value , from which you can get a list of Con values ββdefining the constructors . Then the record type should use RecC , which will give you the list of fields described by the tuple containing the field name, strict field and type .
From there, from there you will do whatever you want.
Edit : for the sake of actually demonstrating the above, here is a really awful quick and dirty function that finds entries:
import Language.Haskell.TH test :: Name -> Q Exp test n = do rfs <- fmap getRecordFields $ reify n litE . stringL $ show rfs getRecordFields :: Info -> [(String, [(String, String)])] getRecordFields (TyConI (DataD _ _ _ cons _)) = concatMap getRF' cons getRecordFields _ = [] getRF' :: Con -> [(String, [(String, String)])] getRF' (RecC name fields) = [(nameBase name, map getFieldInfo fields)] getRF' _ = [] getFieldInfo :: (Name, Strict, Type) -> (String, String) getFieldInfo (name, _, ty) = (nameBase name, show ty)
By importing this into another module, we can use it like this:
data Foo = Foo { foo1 :: Int, foo2 :: Bool } foo = $(test ''Foo)
Loading in GHCi, the value in foo is [("Foo",[("foo1","ConT GHC.Types.Int"),("foo2","ConT GHC.Types.Bool")])] .
Does this give you an idea?
CA McCann
source share