4

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"
0

1 Answer 1

3

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)

((!?) is a safe indexing operator.)

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks so much for your response! When trying to compile your code it complained about "Just" so I removed them both and then it seemed to work fine.
Oh, that's right. I was looking for a total version of head but then I got distracted. I've just fixed it by using (!?), but dropping Just as you said also works.
Thanks I didn’t know about the safe indexing operator!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.