2013-03-27 5 views
10

Ich spiele mit Vorlage Haskell. Ich möchte ein quasi quoter schaffen, die mich Standard initializers für Datensätze erstellen können, also so etwas wieGibt es eine Template-Haskell-Funktion zum Zitieren?

[record| data Config = { shouldDoX = True; featureY :: Integer, optionZ = Nothing } |] 

sollte es ist die gleiche Syntax wie Datendeklarationen eine Funktion

defaultConfig = Config { shouldDoX = True, optionZ = Nothing } 

Grundsätzlich erstellen, erweitert durch Standard Werte. Jetzt ist record ein benutzerdefinierter QuasiQuoter, allerdings gibt es Ausdrücke und Typen, innerhalb derer ich mich selbst nicht analysieren möchte. Idealerweise müsste ich den Block innerhalb der geschweiften Klammern nur in Anweisungen aufteilen und nach = und :: suchen.

Also ich bin auf der Suche nach einer Funktion, die praktisch das gleiche wie zitiert mit [e| ...|] oder [t| ...|] tut. Ich habe Hoogle nach einer Funktion String -> ExpQ oder String -> Q Exp gesucht, aber nichts gefunden.

Falls ich nicht klar darüber bin, wonach ich suche: Ich weiß über QuasiQuoters. Wie ich bereits erwähnte: recordist ein QuasiQuoter. Nun enthält der String, der an meinen Quasi-Quotierer übergeben wird, Ausdrücke (wie Node 7 (Node 8 Nil Nil) Nil) und Typen (wie True oder Maybe (Either A B)). Ich könnte diese selbst analysieren, aber ich hoffe, dass es eine Funktion gibt, die es für mich tun wird, so als ob ich die Zeichenfolge in ein Zitat wie [e|...|] übergeben würde.

Also: Ich bin auf der Suche nach einer Funktion, die ich einen Ausdruck als String oder einen Typ als String feed, und die das entsprechende Exp oder Type Objekt zurückgibt. Ich glaube, dass es in der Q-Monade leben muss, da es den Ausdruck oder Typ basierend auf dem Kontext (genau wie Zitate) auswerten sollte.

functionOfMyDreams "Node 7 (Node 8 Nil Nil) Nil" :: Q Exp 
+5

Ich denke, [haskell-src-meta] (http://hackage.haskell.org/package/haskell-src-meta) könnte das haben, wonach Sie suchen. – hammar

Antwort

1

Sie haben die richtige Idee, aber es wäre eine Funktion wie String -> Q [Dec]

Um ein quasiquoter Sie QuasiQuoter einen Wert vom Typ schaffen sein müssen zu machen, die eine vier Funktionen des Typs hat String -> Q Blah wo Blah das ist Vorlage Haskell-Typ, den Sie einfügen möchten.

In Ihrem Fall müssen Sie nur den Deklarationsquotierer definieren.

quoteRecord :: String -> Q [Dec] 
quoteRecord = ... 

record :: QuasiQuoter 
record = QuasiQuoter (error "record is not a expression quoter") 
        (error "record is not a pattern quoter") 
        (error "record is not a type quoter") 
        quoteRecord 

Sie können dann Ihre Aufzeichnung quasiquoter in einer anderen Datei verwenden

[record| ... |] 

Es gibt einen guten Spaziergang durch auf dem Haskell wiki

Sie auch prüfen, BNFC-meta wollen könnte, die eine quasiquoter generieren von einer Grammatik.

+0

Ich denke, Sie haben meine Frage falsch gelesen. Ich kenne QuasiQuoters. Der Link zu bnfc-meta ist jedoch interessant. Bearbeitete weitere Erklärung in der Frage. – scravy

+1

Es klingt wie, was Sie wollen, ist Antiquierung. Wenn ja, erklärt das Wiki diesen Vorgang. Auch BNFC-Meta produziert Quasiquoters, die antiquoting bieten. –

Verwandte Themen