2011-08-05 16 views
5

Estoy trabajando en el sencillo programa Haskell que busca una cadena JSON de un servidor, la analiza y hace algo con los datos. Los detalles no son realmente pertinentes por el momento, el problema que estoy teniendo es analizar el JSON que se devuelve.Analizando una cadena JSON en Haskell

Obtengo la cadena JSON del servidor como un tipo IO String y no puedo entender cómo analizar eso en un objeto JSON.

Cualquier ayuda sería muy apreciada :)

Aquí está mi código hasta ahora.

import Data.Aeson 
import Network.HTTP 

main = do 
    src <- openURL "http://www.reddit.com/user/chrissalij/about.json" 
    -- Json parsing code goes here 

openURL url = getResponseBody =<< simpleHTTP (getRequest url) 

Nota: estoy usando Data.Aeson en el ejemplo ya que es lo que parece recomendable, sin embargo, yo estaría más que dispuesto a utilizar otra biblioteca.

También se puede cambiar cualquier y todo este código. Si obtiene el

+0

Te ayudaría a ser más específico acerca de lo que te está frenando. ¿Está sacando la cadena de la mónada IO? ¿O es la mecánica del análisis? (Si es el último, echa un vistazo a RWH - hay capítulos enteros dedicados a analizar JSON.) FWIW, valdrá la pena a largo plazo aprender la biblioteca ByteString. Haskell Strings es muy lento. – rtperson

+0

@rtperson. Las cadenas no son automáticamente lentas para analizar. Como Strings son listas de Char, admiten la desestructuración en la cabecera de forma natural y eficiente: esto es exactamente lo que necesita el análisis sintáctico. Por supuesto, las listas de Char son una representación pobre para el texto general con respecto al uso de la memoria. –

+0

@rtperson Es esencialmente ambos. Soy nuevo en Haskell, así que mientras he hecho el análisis JSON en algunos otros idiomas, los detalles de Haskell me están llegando. –

Respuesta

9

Data.Aeson está diseñado para ser utilizado con Attoparsec, por lo que solo le proporciona un Parser que debe usar con Attoparsec. Además, Attoparsec prefiere trabajar en ByteString, por lo que debe modificar la forma en que se realiza la solicitud para obtener un resultado de ByteString en lugar de String.

Esto parece funcionar:

import Data.Aeson 
import Data.Attoparsec 
import Data.ByteString 
import Data.Maybe 
import Network.HTTP 
import Network.URI 

main = do 
    src <- openURL "http://www.reddit.com/user/chrissalij/about.json" 
    print $ parse json src 

openURL :: String -> IO ByteString 
openURL url = getResponseBody =<< simpleHTTP (mkRequest GET (fromJust $ parseURI url)) 

Aquí he acaba de analizar el JSON como llanura Value, pero es probable que desee para crear su propio tipo de datos y escribir una instancia FromJSON para que pueda manejar la conversión ordenadamente

+0

Esto funciona como un encanto. Gracias. No vi en ningún lado que tuve que attoparsec :) –

+0

También estaba tratando de obtener un ByteString, pero estaba luchando con eso también: P –