Usar TemplateHaskell para enumerar todos los nombres en un espacio de nombres
template-haskell (1)
Quiero una función TemplateHaskell
variablesInScope :: Q [Name]
que devuelva una lista de los
Name
de todas las variables en el alcance.
TemplateHaskell obviamente tiene esta información disponible para implementar funciones como
reify :: Name -> Q Info
y
lookupValueName :: String -> Q (Maybe Name)
.
¿La función que quiero existe en algún lugar y la he pasado por alto? ¿O se puede construir fácilmente de alguna manera?
Desafortunadamente, no puedes hacer esto solo con
TH
.
Pruebe el
haskell-src-meta
para analizar el módulo Haskell como
TH AST
.
Sin embargo, requerirá las características IO de
Q
monad para cargar el módulo.
Consulte #9699 para ver la especificación aproximada actual
(1) Extienda ModuleInfo (obtenido de reifyModule) a ModuleInfo [Módulo] [Nombre], donde [Módulo] sigue siendo la lista de importación y [Nombre] contiene la lista de nombres exportados del módulo.
(2) Agregue thisModule :: Q Module que produce el Módulo actual.
(3) Agregue topLevelNames :: Q [Name] produciendo una lista de nombres de nivel superior (tanto exportados como no exportados) enlazados en el módulo actual que serían visibles para reificar.
(4) Agregue nombres anidados :: Q [Nombre] (necesitando un nombre mejor) produciendo una lista de los nombres de nivel superior (anidados) visibles para reificar en este contexto.
(5) Agregue parentNames :: Q [Nombre] (también necesita un mejor nombre) produciendo una lista de los nombres inmediatamente asociados con el contexto de empalme actual, si está disponible. Por ejemplo, foo, bar :: $ (typeSplice) vería [foo, bar], foo = $ (exprSplice) vería [foo] y $ (topLevelDecSplice) vería [].
(6) Opcional Agregue isTopLevel :: Name -> Q Bool para detectar si un nombre está vinculado en el nivel superior (¿del módulo actual?). Algo como esto podría lograrse alternativamente buscando en topLevelNames.