Question

I'm using this code:

{-# LANGUAGE OverloadedStrings #-}

import Data.Aeson
import Data.Maybe
import Data.ByteString.Lazy
import Control.Applicative
import Debug.Trace
import Control.Monad
import qualified Data.Aeson.Types as T

main = do
  res <- liftA show (liftA decodeOriginal (Data.ByteString.Lazy.readFile "./a.json"))
  Prelude.putStrLn res

interpretResult :: Maybe String -> String
interpretResult Nothing = "Error."
interpretResult x = fromJust x

data TotalLine1 = TotalLine1 {
  timestamp :: Integer,
  value :: Integer
} deriving (Eq, Show)

data Original = Original {
  totals :: [TotalLine1]
} deriving (Eq, Show)

instance FromJSON Original where
  parseJSON (Object v) = traceStack "Original" (Original <$> (parseJSON =<< (v .: "visitors.total")))
  parseJSON _ = mzero

instance FromJSON TotalLine1 where
  parseJSON (Object v) = TotalLine1 <$>
                         v .: "timestamp" <*>
                         v .: "value"
decodeOriginal :: ByteString -> Maybe Original
decodeOriginal b = traceStack "decoding" (do
  a <- decode b :: Maybe Original
  return a)

to try and parse JSON like this:

{
visitors.total: [
{
timestamp: 1365548400,
value: 1
},
{
timestamp: 1365548700,
value: 2
},
{
timestamp: 1365549000,
value: 5
},
]
}

But main just returns Nothing every time. What have I done wrong? It seems that even parseJSON isn't being called for Original.

Était-ce utile?

La solution

Your JSON file is not valid.

On the one hand, the names of the fields have to be quoted,

"timestamp"

etc. and on the other, you have a trailing comma in the list of TotalLine1s, which causes the decoding of the ByteString to a Value to fail. Quote the field names and remove the trailing comma, and it works.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top