2013-03-27 21 views
10

Gram z Template Haskell. Chcę stworzyć quasi Quoter która pozwala mi tworzyć domyślne inicjalizatory Records, czyli coś podobnegoCzy istnieje szablon funkcji haskell do cytowania?

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

należy utworzyć funkcję

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

Zasadniczo to ta sama składnia jak deklaracje danych, rozszerzone domyślnie wartości. Teraz record jest niestandardowym QuasiQuoter, jednak istnieją wyrażenia i typy, w których nie chcę się parsować. Idealnie musiałbym tylko podzielić blok wewnątrz nawiasów klamrowych na zdania i poszukać = i ::.

Poszukuję więc funkcji, która skutecznie robi to samo, co cytowanie z [e| ...|] lub [t| ...|]. Szukałem w serwisie Hoogle funkcji String -> ExpQ lub String -> Q Exp, ale niczego nie znalazłem.

Na wypadek, gdy nie miałem jasności co do tego, czego szukam: Wiem o QuasiQuoters. Jak wspomniałem: recordjest quasiQuoter. Teraz ciąg, który jest przekazywany do mojego quasi-quotera, zawiera Wyrażenia (jak Node 7 (Node 8 Nil Nil) Nil) i Typy (jak True lub Maybe (Either A B)). Mógłbym je przetworzyć, ale mam nadzieję, że istnieje funkcja, która zrobi to za mnie, tak jakbym przekazał ciąg znaków do cytatu, takiego jak [e|...|].

A więc: szukam funkcji, którą mogę podać jako String lub Type jako ciąg, i która zwraca odpowiedni obiekt Exp lub Type. Uważam, że musi on żyć w monosie Q, ponieważ powinien ocenić ekspresję lub typ na podstawie kontekstu (tak jak robią to cytaty).

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

Myślę, że [haskell-src-meta] (http://hackage.haskell.org/package/haskell-src-meta) może mieć to, czego szukasz. – hammar

Odpowiedz

1

Masz prawo pomysł, ale byłoby to funkcja jak String -> Q [Dec]

Aby quasiquoter trzeba stworzyć wartość typu QuasiQuoter która posiada cztery funkcje typu String -> Q Blah gdzie Blah jest Szablon typu Haskell, do którego wklejasz.

W twoim przypadku wystarczy tylko zdefiniować zapytanie ofertowe.

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 

Można wtedy użyć swojego rekordu quasiquoter w innym pliku

[record| ... |] 

Jest to dobry spacer na Haskell wiki

też może chcieć sprawdzić BNFC-meta które będą generować quasiquoter z gramatyki.

+0

Myślę, że źle odczytałeś moje pytanie. Wiem o QuasiQuoters. Jednak link do bnfc-meta jest interesujący. Zmieniono dalsze wyjaśnienie tego pytania. – scravy

+1

Wygląda na to, że to, co chcesz, jest już nieaktualne. Jeśli tak, wiki to wyjaśnia. Również BNFC-meta produkuje quasiquoters, które zapewniają antiquoting. –

Powiązane problemy