Basierend auf einem kürzlichen Austausch , I Ich bin davon überzeugt, Template Haskell zu verwenden, um Code zu generieren, der die Sicherheit beim Kompilieren gewährleistet.
Ich muss die Feldnamen und Typen von Datensätzen prüfen. Ich verstehe, dass ich Feldnamen erhalten kann mit constrFields . toConstr :: Data a => a -> [String]
. Aber ich brauche mehr als die Feldnamen, ich muss ihren Typ wissen. Zum Beispiel muss ich die Namen von Feldern kennen, die vom Typ Bool
sind.
Wie konstruiere ich eine Funktion f :: a -> [(String, xx)]
, wo a
der Datensatz ist, String
ist der Feldname und xx
ist der Feldtyp?
Der Typ sollte zusammen mit allem anderen im Info
Wert von reify
verfügbar sein. Insbesondere sollten Sie eine TyConI
erhalten, die a Dec
value , von dem Sie die Liste von Con
Werte, die die Konstruktoren angeben . Ein Datensatztyp sollte dann RecC
verwenden, was Ihnen eine Liste der Felder beschrieben durch ein Tupel , das den Feldnamen enthält, ob das Feld streng ist und der Typ .
Wohin du von dort gehst, hängt davon ab, was du mit all dem machen willst.
Bearbeiten : Um dies zu demonstrieren, hier ist eine wirklich schreckliche schnell und schmutzig Funktion, die Felder finden:
%Vor%Wenn wir das in einem anderen Modul importieren, können wir es so verwenden:
%Vor% Wird in GHCi geladen, ist der Wert in foo
[("Foo",[("foo1","ConT GHC.Types.Int"),("foo2","ConT GHC.Types.Bool")])]
.
Gibt Ihnen das die ungefähre Idee?
Tags und Links haskell template-haskell