Тип должен быть доступен вместе со всем остальным в значении Info
, предоставленном reify
. В частности, вы должны получить TyConI
, который содержит a Dec
значение , из которого вы можете получить список Con
значений, определяющих конструкторы . Тип записи должен затем использовать RecC
, что даст вам список полей , описываемых кортежем , содержащим имя поля, является ли поле строгим, и тип .
Откуда вы идете, зависит от того, что вы хотите со всем этим делать.
Редактировать : Ради реальной демонстрации вышесказанного, вот действительно ужасная быстрая и грязная функция, которая находит поля записи:
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)
Импортируя это в другой модуль, мы можем использовать его так:
data Foo = Foo { foo1 :: Int, foo2 :: Bool }
foo = $(test ''Foo)
При загрузке в GHCi значение в foo
равно [("Foo",[("foo1","ConT GHC.Types.Int"),("foo2","ConT GHC.Types.Bool")])]
.
Это дает вам грубую идею?