Aeson: derive some (but not all) fields of a struct
我有一个大型结构,我需要它是 FromJSON 的一个实例,以便我可以将我的 json 数据解析到其中。
我想自动派生,但是单个字段需要"特别注意",因为它是 json 中的一个对象,我希望它是我的结构中的值的数组。在不编写重复所有字段的巨大 FromJson 实现的情况下如何做到这一点?
示例 json:
1 | {"myobject": {"one": 1,"two": 2}, ...many_more_fields...} |
示例结构:
1 2 3 4 |
我该如何优雅地做到这一点?
你应该为你的特殊领域创建一个
1 2 3 4 5 6 7 8 | newtype MySpecialType = MySpecialType [Int] instance FromJSON MySpecialType where .... data MyStruct = MyStruct { myobject:: MySpecialType, ... } |
现在
为了避免在整个代码库中使用 Paul Johnson 非常好的答案中的 newtype,您还可以将您的类型概括如下,将
1 2 3 4 5 6 7 8 9 10 |
上面的
我也刚刚写了一篇关于"类型手术"的博文,适用于这种问题,这样你就可以保持原来的类型不被修改。
generic-data-surgery 库可以派生出与上述
1 2 3 4 5 6 7 8 9 10 11 | import Generic.Data.Surgery (fromOR, toOR', modifyRField) -- The original type data MyStruct = MyStruct { myobject :: [Int], ... } deriving (Generic) instance FromJSON MyStruct where parseJSON = fmap (fromOR . modifyRField @"myobject" (\\(MySpecialType i) -> i) . toOR') . genericParseJSON defaultOptions |