2011-10-06 11 views
9

Sto cercando di analizzare una chiamata a un'API in un tipo di record Haskell utilizzando la libreria Aesonparsing jsons complicati con Aeson

sto usando pagine di Wikipedia, e analisi al titolo e un elenco di link . Un campione sarebbe questo,

{"query":{"pages":{"6278041":{"pageid":6278041,"ns":0,"title":"Lass","links":[{"ns":0,"title":"Acronym"},{"ns":0,"title":"Dead Like Me"},{"ns":0,"title":"Donna Lass"},{"ns":0,"title":"George Lass"},{"ns":0,"title":"Girl"},{"ns":0,"title":"Lassana Diarra"},{"ns":0,"title":"Lightning Lass"},{"ns":0,"title":"Real Madrid"},{"ns":0,"title":"Shadow Lass"},{"ns":0,"title":"Solway Lass"},{"ns":0,"title":"Szymon Lass"},{"ns":0,"title":"The Bonnie Lass o' Fyvie"},{"ns":0,"title":"The Tullaghmurray Lass"},{"ns":0,"title":"Woman"},{"ns":12,"title":"Help:Disambiguation"}]}}}} 

e vorrei analizzarlo al titolo e un elenco di link a un tipo di dati come questo.

data WikiPage = WikiPage { title :: String, 
          links :: String } 

Quale codice Al momento ho è questo,

instance FromJSON WikiPage where 
    parseJSON j = do 
    o <- parseJSON j 
    let id = head $ o .: "query" .: "pages" 
    let name = o .: "query" .: "pages" .: id .: "title" 
    let links = mapM (.: "title") (o .: "query".: "pages" .: id .: "links") 
    return $ WikiPage name links 

sto ottenendo l'errore,

Couldn't match expected type `Data.Text.Internal.Text' 
       with actual type `[Char]' 
    In the second argument of `(.:)', namely `"title"' 

Io davvero non capisco che cosa sta succedendo, mi sento come se ci deve essere un problema con il modo in cui sto mappando i collegamenti ma non sono sicuro di cosa si debba fare esattamente. Inoltre non capisco come dovrei usare id nella seconda stringa di query dato che si tratta di un parser (sono sicuro di dover usare l'applicativo qui da qualche parte ma non sono sicuro di come.) Non ho trovato qualsiasi esempio che decompone i jsons più complicati come questo.

+0

in aggiunta al problema e'OverloadedStrings', quelli 'let's non sembrano giusti, ad es. dovresti sostituire 'let name =' per 'name <-', poiché' name' è attualmente di tipo 'Parser a' ma vuoi' a' – hvr

risposta

15

Sto anche cercando di capire aeson. Ho avuto lo stesso problema che avevi, e l'ho risolto aggiungendo {-# LANGUAGE OverloadedStrings #-} nella parte superiore del mio file sorgente. Sono molto nuovo per Haskell, ma credo che aggiunga un'estensione non ufficiale al linguaggio, presumibilmente per consentire alle stringhe di raddoppiare come altri tipi di dati simili a stringhe.

+5

Che è corretto. Puoi anche usare 'Data.Text.pack' per convertire manualmente un' String' in 'Text'. – hammar

+0

Ha avuto lo stesso problema (con una libreria diversa, Campfire) e "pack" risolto per me. –