J'ai des données qui sont une carte. Pour rendre la question plus concrète, supposons qu'elle soit représentée comme une assoc-list type D val = [(Key,val)]
(ou comme type D val = Map Key val
).Comment implémenter toJSON pour une assoc-list produisant un objet avec des paires clé-valeur de manière générique (en utilisant Aeson)?
Key
est un type "enum" - une somme de constructeurs nulaires, .: par exempleDonnées clés = C1 | C2 | C3
Il doit y avoir
instance ToJSON
pourval
.
Je voudrais mettre en œuvre
instance ToJSON val => ToJSON (D val)
qui serait comme instance Map String val
(la production d'un objet avec les paires clé-valeur correspondant) (an example, another example pour HashMap
s), seulement plus générique.
Plus générique signifie que je ne suis pas limité à String
ou Text
comme clé (de telles instances pour Map
se trouvent dans le paquet aeson).
Je veux apprendre à utiliser les mécanismes génériques dans aeson pour le faire de manière concise.
Aeson déjà peut convertir « énumérations » aux chaînes JSON, et aussi (C val1 val2 ...)
à des objets avec une seule touche (le nom du constructeur, comme cela, je suppose: { "C":[val1,val2,...] }
) avec genericToJSON defaultOptions{ sumEncoding = ObjectWithSingleField }
. Et une autre conversion qui utilise les noms de constructeurs est avec les options par défaut pour les types de données avec des constructeurs non-nullary: alors le nom du constructeur devient la valeur d'une clé "tag"
. Je pourrais utiliser un code similaire.
Je pense que même une telle instance (pour les cartes dont les clés proviennent d'enums) serait utile à la bibliothèque. Mais AFAIU ni ni generic-aeson (qui a ajouté quelques options de conversion plus agréable) a une telle conversion prédéfinie.
"Je pense que même une telle instance (pour les cartes dont les clés proviennent d'enums) serait utile à la bibliothèque" -> Je n'ai jamais eu besoin de cette instance, votre cas d'utilisation semble assez spécifique, je ne suis pas sûr il serait particulièrement utile d'avoir défini dans le paquet 'aeson'. Le vrai problème que je vois ici est la conversion de 'Map Key val' en' Map Text val', puis la sortie. Pourquoi ne pas simplement écrire une fonction qui convertit vos clés en un type qui utilise déjà 'ToJSON' au lieu de se soucier de la programmation générique? – bheklilr
@bheklilr J'aime que les noms de constructeurs de Haskell soient réutilisés comme noms de clés. Je prévois de varier cette énumération lorsque je travaille sur mon projet, donc je ne veux pas maintenir les fonctions pour le texte <-> Conversions de clés (l'autre direction peut être nécessaire pour FromJSON, eh bien, pas nécessairement, car aeson peut vivre avec single ' Options pour les deux directions de conversion, ayant un seul 'fieldLabelModifier' pour les deux fronts, et je vois comment cela peut être fait pour une énumération.) –
@bheklilr Je pensais que c'était en quelque sorte dans l'esprit d'Aeson de représenter beaucoup de données Haskell natives types en tant que JSON sans compter sur les conversions au texte fournies par l'utilisateur. Je trouve cela joyeux. –