Parsing nested JSON with Haskell and Aeson I'm trying to reduce nested JSON data using Haskell and Aeson without creating data/record types.
The following code works, but seems ugly and unreadable.
Any advice on cleaning this up would be great.  

Thank you

import GHC.Exts
import Data.Maybe (fromJust)
import Data.Text (Text)
import Data.Aeson
import qualified Data.HashMap.Strict as M

testVal :: Value
testVal = Object $ fromList [
  ("items", Array $ fromList [ 
    (Object $ fromList [
      ("entity", (Object $ fromList [ 
        ("uuid", String "needed-value1")]))]),
    (Object $ fromList [
      ("entity", (Object $ fromList [ 
        ("uuid", String "needed-value2")]))])
    ])]

getItems :: Value -&gt; Value
getItems (Object o) = fromJust $ M.lookup "items" o

getEntities :: Value -&gt; Value
getEntities (Array a) = Array $ fmap (\(Object o) -&gt; fromJust $ M.lookup "entity" o) a

getUuids :: Value -&gt; Value
getUuids (Array a) = Array $ fmap (\(Object o) -&gt; fromJust $ M.lookup "uuid" o) a

getTexts :: Value -&gt; [Text]
getTexts (Array a) = toList $ fmap (\(String s) -&gt; s) a


someFunc :: IO ()
someFunc = do
  let items = getItems testVal
      entities = getEntities items
      uuids = getUuids entities
      texts = getTexts uuids
  print texts


output:

["needed-value1","needed-value2"]
You should really use an algebraic data type to implement your JSON interface. You can even automatically derive FromJSON instances with DeriveGeneric GHC extension, e.g.

{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}

import GHC.Generics
import Data.Aeson
import Data.ByteString.Lazy (ByteString)

data Query = Query { items :: [Entity] }
             deriving (Show, Generic)

instance FromJSON Query -- automatically derived instance by DeriveGeneric

data Entity = Entity { uuid :: String }
              deriving (Show)

instance FromJSON Entity where
    parseJSON = withObject "Entity" $ \v -&gt; do
        -- as your json data is additionally nested with an entity object
        -- extract the entity object first
        obj &lt;- v .: "entity"
        -- then extract the uuid field from the entity object
        uid &lt;- obj .: "uuid"
        return $ Entity uid

testVal :: ByteString
testVal = "{\"items\": [{\"entity\": {\"uuid\": \"needed-value1\"}}, {\"entity\": {\"uuid\": \"needed-value2\"}}]}"

main :: IO ()
main = do
    let mayQuery = decode testVal
    case mayQuery of
        Just query -&gt; print $ map uuid $ items query
        Nothing -&gt; putStrLn "JSON parsing error"


I transformed your sample Value into a JSON string, to make the parsing clearer.

The FromJSON instance for Query is automatically derived, if you want to write it by hand, you can do this in analogy to the FromJSON instance of Entity.

This way of parsing your JSON data is very scalable, as you can easily add new fields to your data types, without complicating your code.