2011-10-06 20 views
9

Estoy tratando de analizar una llamada a una API en un tipo de registro Haskell usando la Biblioteca Aesónanálisis jsons complicados con Aesón

estoy usando páginas de Wikipedia, y análisis de ellos para el título y una lista de enlaces . Una muestra sería esto,

{"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"}]}}}} 

y me gustaría analizarlo con el título y una lista de enlaces en un tipo de datos de esta manera.

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

¿Qué código tengo actualmente es esto,

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 

estoy recibiendo el error,

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

Realmente no entiendo lo que pasa, siento que hay debe ser un problema con la forma en que estoy mapeando los enlaces, pero no estoy seguro de qué se debe hacer exactamente. Tampoco entiendo cómo se supone que debo usar id en la segunda cadena de consulta, ya que es un analizador sintáctico (estoy seguro de que necesito utilizar el aplicativo aquí en alguna parte pero no estoy seguro de cómo). No he encontrado cualquier ejemplo que descompone jsons más complicados como este.

+0

además del problema ''OverloadedStrings', esos' let's no se ven bien, p. deberías reemplazar 'let name =' por 'name <-', ya que' name' es actualmente de tipo 'Parser a' pero quieres' a' – hvr

Respuesta

15

También estoy tratando de averiguar aeson. Tuve el mismo problema que estaba teniendo, y lo resolví agregando {-# LANGUAGE OverloadedStrings #-} en la parte superior de mi archivo fuente. Soy nuevo en Haskell, pero creo que agrega una extensión no oficial al lenguaje, presumiblemente para permitir que las cadenas se dupliquen como otros tipos de datos tipo cadena.

+5

Eso es correcto. También puede usar 'Data.Text.pack' para convertir manualmente' String' a 'Text'. – hammar

+0

Tuve el mismo problema (con una biblioteca diferente, Campfire) y 'paquete' resuelto para mí. –