Используя линзы из пакета lens-aeson
, я думаю, что вам нужно что-то вроде:
Object $ (x ^. _Object & sans "action") <> (x ^. key "action"._Object)
Здесь sans
происходит от Control.Lens.At
и удаляет верхний уровень "action"
, оставляя Object
(т.е. HashMap Text Value
) с оставшимися клавишами верхнего уровня. Получатель key "action"._Object
выбирает значение "action"
верхнего уровня и извлекает Object
. Два Object
можно объединить с помощью <>
и обернуть в Value
с помощью конструктора Object
.
Полный код:
{-# LANGUAGE OverloadedStrings #-}
module AesonLens where
import Data.Aeson
import Data.Aeson.Lens -- from lens-aeson
import Control.Lens
ex1 :: IO Value
ex1 = do Just val <- decodeFileStrict "aesonlens.json"
return val
main = do
x <- ex1
print $ Object $ (x ^. _Object & sans "action") <> (x ^. key "action"._Object)
с входным файлом "aesonlens.json"
:
{
"action": {
"action": "reply",
"replies": [
"Does this work?",
"What about this?"
]
},
"suggestions": [1,2,3],
"inputs": [4,5,6]
}
выход:
> main
Object (fromList [("inputs",Array [Number 4.0,Number 5.0,Number 6.0]),
("action",String "reply"),("replies",Array [String "Does this work?",
String "What about this?"]),("suggestions",Array [Number 1.0,Number 2.0,
Number 3.0])])