json - 使用 Aeson 将嵌套的 JSON 解析为元组列表
问题描述
假设我有以下结构:
data AddressDto = AddressDto
{ addressDtoId :: UUID
, addressDtoCode :: Text
, addressDtoCity :: Maybe Text
, addressDtoStreet :: Text
, addressDtoPostCode :: Text
} deriving (Eq, Show, Generic)
instance FromJSON AddressDto where
parseJSON = genericParseJSON $ apiOptions "addressDto"
instance ToJSON AddressDto where
toJSON = genericToJSON $ apiOptions "addressDto"
toEncoding = genericToEncoding $ apiOptions "addressDto"
这如你所料。
现在说我要解析格式的 JSON 结构:
{ UUID: AddressDto, UUID: AddressDto, UUID: AddressDto }
一个合理的 Haskell 表示似乎是:
data AddressListDto = AddressListDto [(UUID, AddressDto)]
像这样创建一个辅助函数:
keyAndValueToList :: Either ServiceError AddressListDto -> Text -> DiscountDto -> Either ServiceError AddressListDto
keyAndValueToList (Left err) _ _ = Left err
keyAndValueToList (Right (AddressListDto ald)) k v = do
let maybeUUID = fromString $ toS k
case maybeUUID of
Nothing -> Left $ ParseError $ InvalidDiscountId k
Just validUUID -> Right $ AddressListDto $ (validUUID, v) : ald
最后是 FromJSON 的一个实例:
instance FromJSON AddressListDto where
parseJSON = withObject "tuple" $ \o -> do
let result = foldlWithKey' keyAndValueToList (Right $ AddressListDto []) o
case result of
Right res -> pure res
Left err -> throwError err
这无法编译:
Couldn't match type ‘aeson-1.4.5.0:Data.Aeson.Types.Internal.Value’
with ‘AddressDto’
Expected type: unordered-containers-0.2.10.0:Data.HashMap.Base.HashMap
Text AddressDto
两个问题:
1) 如何确保哈希图中的嵌套值被正确解析为 AddressDto。2)如何避免将初始值强制为一个?有没有我可以使用的函数而foldlWithKey'
不是让我像这样包装初始值?
解决方案
有趣的答案。要实现parseJSON
,您可以使用
parseJSON :: Value -> Parser (HashMap Text AddressDto)
...但更好的是,为什么不使用类型别名而不是新的数据类型,所以:
type AddressListDto = HashMap UUID AddressDto
这已经有一个合适的FromJSON
实例,所以你甚至不需要自己编写任何代码。
推荐阅读
- unity3d - 将 AdMob 导入我的统一项目不显示资产菜单
- jekyll - 在 Jekyll 的主页中列出带有自己标签的集合/帖子
- spring - 使用 POJO 如何帮助 Spring
- machine-learning - F1 测量与精度比较两个模型
- json - 需要将以下数据转成JSON
- javascript - 在 for 循环内的函数中调用 ajax 调用失败
- c# - ASP.Net Core 2.2 - 方法重载出现在 Visual Studio 中,但在运行时不起作用
- audio - 为什么音频文件加密是在频域完成的?
- html - 在导航栏中显示个人资料图像
- sharp-snmp - 正确解析 MAC 地址