2011-10-17 4 views
4

Ce problème est lié à la question this.Essayer d'analyser JSON récursive, suis-je sur la bonne voie?

Voici le type de données que je veux faire de la JSON:

data ProdObject = MKSpair (Text, Text) 
       | MKSLpair (Text, [Text]) 
       | MKSOpair (Text, ProdObject) 
       | MKObject ProdObject 
       | End 
       deriving Show 

Here est un échantillon des données, je travaille avec, en plus d'une généralisation de l'ensemble.

Voici ma définition d'instance, qui provoque une erreur. J'ai utilisé this comme référence. Je ne suis pas sûr si l'erreur me dit de réparer mon type, ou que je suis loin. Si l'erreur est vraiment simple, je voudrais des conseils sur la façon de réparer mon type, ainsi que des conseils sur ce que je peux faire d'autre, mais je n'ai pas encore remarqué.

instance FromJSON ProdObject where 
    parseJSON (Object o) = MKObject <$> parseJSON o 
    parseJSON (String s, String t) = MKSpair (s, t) 
    parseJSON (String s, Object o) = MKSOpair (s, MKObject <$> parseJSON o) 
    parseJSON (String s, Array a) = MKSLpair (s, V.toList a) 
    parseJSON (Done d) = End 
    parseJSON _  = mzero 

est ici l'erreur que j'ai en ce moment:

ghcifoo> :load test 
[1 of 1] Compiling Main    (test.hs, interpreted) 

test.hs:23:52: 
    Couldn't match expected type `Value' 
       with actual type `Data.Map.Map Text Value' 
    Expected type: Value 
     Actual type: Object 
    In the first argument of `parseJSON', namely `o' 
    In the second argument of `(<$>)', namely `parseJSON o' 
Failed, modules loaded: none. 

Mise à jour: J'ai refait mon type de données, si je ne me trompe pas, j'ai un type fantôme. Si je me trompe, retour à la table à dessin

data ProdObject = MKSpair (Text, Text) 
       | MKSLpair (Text, [Text]) 
       | MKSOpair (Text, ProdObject) 
       | MKObject ProdObject (k,v) 
       | End 

J'ai également reflété ce changement dans mon exemple, bien que d'une manière incomplète. Je le mentionne juste pour demander si je suis sur la bonne voie ou non.

parseJSON (Object (k,v)) = MKObject ... 

Si je suis sur la bonne voie, je pense que je peux soit comprendre le reste, ou au moins poser une question précise. Réaction quelqu'un?

Répondre

1

Dans cette équation:

parseJSON (Object o) = MKObject <$> parseJSON o 

o est de type Map Text Value, mais parseJSON a le type Value -> Parser a, donc vous pouvez évidemment pas appliquer parseJSON-o.

, vous avez également une erreur de type ici:

parseJSON (String s, String t) = MKSpair (s, t) 

Le type de parseJSON est Value -> Parser a, mais vous essayez de match contre (Value, Value).

de même pour cette ligne:

parseJSON (Done d) = End 

Done est pas un constructeur de type Value.


Je ne comprenais pas pourquoi vous avez besoin du type ProdObject récursive; voici comment je résoudre ce problème:

data Outer = Outer { 
    oName :: Text, 
    oProducts :: M.Map Text Inner 
} deriving Show 

data Inner = Inner { 
    iQA :: Text, 
    iVM :: Text, 
    iAvailable :: V.Vector Text 
} deriving Show 

instance FromJSON Outer where 
    parseJSON (Object o) = Outer <$> o .: "name" <*> o .: "products" 
    parseJSON _ = mzero 

instance FromJSON Inner where 
    parseJSON (Object o) = Inner <$> o .: "qa" <*> o .: "vm" <*> o .: "available" 
    parseJSON _ = mzero 

liste complète des codes se trouve on Github.

+0

Je pense que ce que j'ai est le mauvais concept de ce à quoi ressemble un objet JSON. –

+0

Je pensais que ça devait être récursif, parce que les données que j'avais reçues me semblaient récursives. Merci pour la solution! –

Questions connexes