Ich versuche herauszufinden, wie generische Herleitung modelliert nach deriveJSON
zu tun. I definiert einen einfachen Typ Datensatz Stildaten Konstruktor wie folgt:Zugriff auf Datensatzname und Funktion in Generika
data T = C1 { aInt::Int, aString::String} deriving (Show,Generic)
Was ich möchte eine generische ableitbar Funktion zu definieren, zu tun ist, die die Daten Konstrukteurs oben nimmt und gibt ein Baumeister mit den Datensatznamen und die Funktionen - nur ein Spielzeug-Code - wollen wir, dass wir es für jeden Datentyp mit einem Rekord Syntax ABuilder
generic so verwenden können (wie deriveJSON
in Aeson
) machen:
{-# LANGUAGE DeriveGeneriC#-}
import GHC.Generics
data T = C1 { aInt::Int, aString::String} deriving (Show,Generic)
-- Some kind of builder output - String here is a stand-in for the
-- builder
class ABuilder a where
f :: a -> String
-- Need to get the record field name, and record field function
-- for each argument, and build string - for anything that is not
-- a string, we need to add show function - we assume "Show" instance
-- exists
instance ABuilder T where
f x = ("aInt:" ++ (show . aInt $ x)) ++ "," ++ ("aString:" ++ (aString $ x))
Was ich kann nicht herausfinden, wie zu bekommen der Name des Eintrags und die Funktion. Hier ist mein Versuch in ghci 7.10.3
. Ich könnte den Namen des Datentyps erhalten, aber ich kann nicht herausfinden, wie man Namen und Funktionen daraus erhält.
$ ghci Test.hs
GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling Main (Test.hs, interpreted)
Ok, modules loaded: Main.
*Main> datatypeName . from $ (C1 {aInt=1,aString="a"})
"T"
*Main> :t from (C1 {aInt=1,aString="a"})
from (C1 {aInt=1,aString="a"})
:: D1
Main.D1T
(C1
Main.C1_0T
(S1 Main.S1_0_0T (Rec0 Int) :*: S1 Main.S1_0_1T (Rec0 String)))
x
*Main>
Ich werde schätzen Hinweise, wie die Satznamen zu erhalten und die Funktion in Generics
. Wenn TemplateHaskell
ist besser Ansatz für die Definition Generic
Instanz ABuilder
, werde ich schätzen hören warum. Ich hoffe, bei Generics
bei der Kompilierung zu bleiben, wenn die Lösung einfach ist. Ich habe festgestellt, dass Aeson
TemplateHaskell
für deriveJSON
Teil verwendet. Deshalb meine Frage über TemplateHaskell
oben, um zu sehen, ob es etwas gibt, das ich hier vermisse (ich benutze ghc 7.10.3
und benötige keine Rückwärtskompatibilität mit älteren Versionen).
sehen Wenn Sie 'Generic' ableiten, Die generierten Typen, die Metadaten darstellen (zB 'C1_0T',' S1_0_0T', usw.) haben Instanzen der entsprechenden Klassen ('Datatype',' Constructor', 'Selector'). Diese Instanzen ermöglichen Ihnen den Zugriff auf diese Metadaten. Sie benötigen eine Klasse, um die verschiedenen generischen Konstruktoren zu behandeln, wie in allen Beispielen für Generika. – user2407038
@ user2407038, yep, ich weiß. Meine Frage betrifft den Zugriff auf Datensatznamen und Funktionen. Generische Beispiele, die ich bisher gesehen habe, haben diese Szenarien nicht. – Sal
Es gibt keine Magie - rufen Sie die Methoden der Typklassen auf, dh ['Selector'] (https://hackage.haskell.org/package/base-4.8.2.0/docs/GHC-Generics.html#t:Selector) über die entsprechenden Werte. Genau wie Sie 'datypeName' verwendet haben. Sie haben keinen Code zur Verfügung gestellt, so dass es schwer ist, mehr zu sagen. – user2407038