Reputation: 23
Suppose there's this record:
data Place = Place
{ details :: PlaceDetails
, amenities :: [Amenity]
, photos :: [PlacePhoto]
} deriving (Generic)
I've implemented toEncoding
for every data type, but I'd like to combine those fields in the Place
type.
For now, it's like this:
instance ToJSON Place where
toEncoding Place{..} =
pairs $ "details" .= details
<> "amenities" .= amenities
<> "photos" .= photos
I use toEncoding
to preserve a certain order that I want. However, I'd like to remove that details
key from the encoding, so that all the fields from PlaceDetails
are on the same level as amenities
and photos
, without manually specifying all those fields, as PlaceDetails
is quite big.
How would I do that? I know that I can merge [Value]
using HML.unions
but I've only managed to do that with toJSON
, not toEncoding
.
What I currently have:
{
"details": {
"id": "place_6de6cda0f8524a6f9c264c84afdbadad",
"name":"somename",
"description":"some description",
"other": "a lot more fields"
}
"amenities": []
"photos": []
}
This is what I want:
{
"id":"place_6de6cda0f8524a6f9c264c84afdbadad",
"name":"somename",
"description":"some description",
"other": "a lot more fields",
"amenities": []
"photos": []
}
Thanks.
Upvotes: 1
Views: 198
Reputation: 64740
An Aeson Object is just a hashmap which you can union using <>
(infix) or mappend
.
For example:
#!/usr/bin/env cabal
{- cabal:
build-depends: base, aeson
-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE RecordWildCards #-}
module Main where
import Data.Aeson
import GHC.Generics
main :: IO ()
main = print (encode (Place (Foo 1 2) (Bar 3 4)))
data Foo = Foo {foo1 :: Int, foo2 :: Int}
deriving (Eq,Ord,Show,Generic,ToJSON)
data Bar = Bar {bar1 :: Int, bar2 :: Int}
deriving (Eq,Ord,Show,Generic,ToJSON)
data Place = Place { foo :: Foo , bar :: Bar }
deriving (Eq,Ord,Show,Generic)
instance ToJSON Place where
toJSON Place{..} =
let Object b = toJSON bar
in Object ([("foo",toJSON foo)] <> b)
And we can run this:
% chmod +x so.hs && ./so.hs
... snippet out build info ...
"{\"bar1\":3,\"foo\":{\"foo2\":2,\"foo1\":1},\"bar2\":4}"
Upvotes: 1