2016-02-29 3 views
1

Si j'ai un type de données sur mesure pour l'analyse syntaxique JSON avec Aesondériver par exemple automatiquement pour le type de données personnalisées avec Aeson/JSON

data Response = Response 
    { response :: [Body] 
    } deriving (Show) 

instance FromJSON Response where 
    parseJSON (Object v) = Response <$> v .: "response" 
    parseJSON _ = mzero 

data Body = Body 
    { body_id    :: Int 
    , brandId    :: Int 
    } deriving (Show) 

instance FromJSON Body where 
    parseJSON (Object v) = Body 
     <$> v .: "id" 
     <*> v .: "brandId" 
    parseJSON _ = mzero 

raw :: BS.ByteString 
raw = "{\"response\":[{\"id\":5977,\"brandId\":87}]}" 

donnant:

λ> decode raw :: Maybe Response 
Just (Response {response = [Body {body_id = 5977, brandId = 87}]}) 

Comment les instances dois-je tirer pour FromJSON automatiquement?

J'ai essayé:

data Response = Response 
    { response :: [Body] 
    } deriving (Show,Generic) 

data Body = Body 
    { body_id    :: Int 
    , brandId    :: Int 
    } deriving (Show,Generic) 

instance FromJSON Response 
instance FromJSON Body 

comme cela a été suggéré de quelques tutoriels, mais qui donne:

λ> :l response.hs 
[1 of 1] Compiling Response   (response.hs, interpreted) 

response.hs:19:22: 
    Can't make a derived instance of `Generic Response': 
     You need DeriveGeneric to derive an instance for this class 
    In the data declaration for `Response' 

response.hs:24:22: 
    Can't make a derived instance of `Generic Body': 
     You need DeriveGeneric to derive an instance for this class 
    In the data declaration for `Body' 
Failed, modules loaded: none. 

ce que je fais mal?

Répondre

11

Ce que l'erreur vous dit est que vous devez activer l'extension DeriveGeneric pour que cela fonctionne. Donc, vous devez ajouter:

{-# LANGUAGE DeriveGeneriC#-} 

droite en haut de votre fichier, ou compilez en utilisant le drapeau -XDeriveGeneric.

+0

Merci! qui l'a réparé. et aussi merci d'avoir édité mon post. – matthias

+1

encore une chose. Vous remarquerez le "id" dans 'raw =" {\ "response \": [{\ "id \": 5977, \ "brandId \": 87}]} "'; est-il possible d'écraser une partie de l'instance dérivée automatiquement? id est évidemment réservé et le JSON qui est récupéré a "id" dans celui-ci et je préférerais ne pas nous id dans mon type de données. – matthias

+0

@matthias Je doute que vous puissiez le faire. Mais je ne suis pas un expert d'Aeson. Vous pouvez essayer d'ouvrir une nouvelle question à propos de ce problème. – Bakuriu