Im struggling to parse the below JSON using the Aeson library.
Im only interested in getting file1 but I cant seem to manage it.
Does anyone have suggestions?
The JSON
{"files":[["file1.wav",["file2.jpg","file3.jpg"]]]}
My code
data File = File Text deriving (Show, Generic, ToJSON)
instance FromJSON File where
parseJSON jsn = do
arrays <- parseJSON jsn
let x = arrays !! 0 !! 0
return $ File x
Error message
"Error in $.files[0][1]: parsing Text failed, expected String, but encountered Array"
The problem is using parseJSON
to parse jsn
into a homogeneous list. But "file1.wav"
is a string and ["file2.jpg", "file3.jpg"]
is not a string.
A simple solution is to directly pattern-match on json
, which is a Value
which can contain a heterogeneous Array
(in spite of its name, it's actually a synonym for a Vector
from the vector library).
{-# LANGUAGE OverloadedStrings #-}
import Data.Aeson
import qualified Data.Vector as V
import Data.Text (Text)
newtype File = File Text deriving Show
instance FromJSON File where
parseJSON json = do
Array arr <- pure json
Just (Array arr0) <- pure (arr V.!? 0)
Just (String txt) <- pure (arr0 V.!? 0)
pure (File txt)
main :: IO ()
main = print (decode' "[[\"file1\", [\"file2\", \"file3\"]]]" :: Maybe File)