2014-10-16 11 views
72

Ich möchte eine TemplateHaskell-Funktion variablesInScope :: Q [Name], die eine Liste der Name 's aller Variablen im Bereich zurückgibt. TemplateHaskell verfügt offensichtlich über diese Informationen, um Funktionen wie reify :: Name -> Q Info und lookupValueName :: String -> Q (Maybe Name) zu implementieren.Verwenden von TemplateHaskell zum Auflisten aller Namen in einem Namespace

Funktioniert die Funktion, die ich will irgendwo und ich habe es einfach übersehen? Oder kann es irgendwie leicht gebaut werden?

+2

Ich bin ziemlich sicher, dass Sie dies nicht mit nur TH tun können, aber Sie können 'haskell-src-meta' verwenden, um ein Haskell-Modul als TH AST zu analysieren. – user2407038

+1

Müsste das die Verwendung der IO-Funktionen der 'Q'-Monade erfordern, um das Modul zu laden, und dann dieses an 'haskell-src-meta' senden? Huch. Außerdem kann dies nicht eindeutig festlegen, welcher Name in dem bestimmten Bereich verwendet wird, in dem sich der Spleiß befindet. –

+1

Ja, Sie müssen IO verwenden, um die Datei tatsächlich zu lesen. Ich bin mir nicht sicher, ob ich Ihre zweite Aussage verstehe - warum sollten Sie sich aufklären, wenn Sie * alle * Namen bekommen? Sie könnten ein Ticket für eine Feature-Anfrage öffnen, ich vermute, dass der zugrunde liegende Mechanismus, der TH antreibt, sowieso alle gültigen Namen hat. – user2407038

Antwort

1

Leider können Sie dies nicht mit TH allein tun. Probieren Sie haskell-src-meta aus, um das Haskell-Modul als TH AST zu analysieren.

Es werden die IO-Funktionen der Q Monade benötigt, um das Modul zu laden.

Beziehen Sie sich auf https://ghc.haskell.org/trac/ghc/ticket/9699#ticket die aktuelle grobe Spezifikation zu sehen

(1) Verlängern Module (von reifyModule) erhaltene Module [Modul] [Name], wobei [Module] noch der Import Liste und [Name] enthält die Liste der exportierten Namen des Moduls.

(2) Add thisModul :: Q Modul, das das aktuelle Modul erzeugt.

(3) Hinzufügen topLevelNames :: Q [Name] erzeugt eine Liste von Top-Level-Namen (sowohl exportierte als auch nicht-exportierte) gebunden in das aktuelle Modul, das sichtbar wäre zu vereinheitlichen.

(4) Fügen Sie nestedNames :: Q [Name] hinzu (benötigt einen besseren Namen), um eine Liste der Namen der nicht-obersten Ebene (verschachtelt) zu erstellen, die in diesem Kontext zu verify sichtbar sind.

(5) Fügen Sie parentNames :: Q [Name] hinzu (ebenfalls einen besseren Namen benötigend), um eine Liste der Namen zu erzeugen, die sofort dem aktuellen Spleißkontext zugeordnet sind, falls verfügbar. Beispiel: foo, bar :: $ (typeSplice) würde [foo, bar] sehen, foo = $ (exprSplice) würde [foo] sehen und $ (topLevelDecSplice) würde [] sehen.

(6) Optional IsTopLevel :: Name -> Q Bool hinzufügen, um festzustellen, ob ein Name auf der obersten Ebene (des aktuellen Moduls?) Gebunden ist. So etwas könnte alternativ durch das Durchsuchen von topLevelNames erreicht werden.

Verwandte Themen