【发布时间】:2018-04-21 01:58:15
【问题描述】:
我有一个 sum 数据类型,如下所示:
data Declaration =
IndDecl { what :: String, name :: String, argnames :: Maybe [String], constructors :: [Constructor] }
| TypeDecl { what :: String, name :: String, argnames :: Maybe [String], value :: Maybe Arg }
| FixDecl { what :: String, fixlist :: Maybe [Fixitem] }
| TermDecl { what :: String, name :: String, typ :: Maybe Typ, value :: Maybe Arg }
deriving (Show, Eq)
我正在使用 Data.Aeson.TH 和以下选项派生 JSON 序列化器/反序列化器:
$(deriveJSON defaultOptions { sumEncoding = UntaggedValue } ''Declaration)
这会从 JSON 构造中删除标签。同时,我觉得我的数据已经有了一个标签,就是what这个字段。它可以是以下之一:
IndDecl : "decl:ind"
FixDecl : "decl:fix"
等等。因此,我为我的 JSON 反序列化对象使用 Untagged 配置这一事实有点令人担忧。如何让 Aeson 根据我的数据已有的标签派生 JSON 存根?
或者删除what字段并让Aeson添加一个描述构造函数的“标签”字段可能是一个更好的主意?
编辑:我通过添加标签字段尝试了后者。现在看起来像:
-- Declarations
data Declaration =
IndDecl { what :: String, tag :: String, name :: String, argnames :: Maybe [String], constructors :: [Constructor] }
| TypeDecl { what :: String, tag :: String, name :: String, argnames :: Maybe [String], value :: Maybe Arg }
| FixDecl { what :: String, tag :: String, fixlist :: Maybe [Fixitem] }
| TermDecl { what :: String, tag :: String, name :: String, typ :: Maybe Typ, value :: Maybe Arg }
deriving (Show, Eq)
但是,我收到以下错误:
$.declarations[0] 中的错误:键“标签”不存在
我不明白,因为我创建了一个“标签”字段。
【问题讨论】:
-
您误解了 Aeson 的工作原理。尝试序列化您的数据,看看会发生什么。
-
Data.Aeson.THdocumentation 建议您希望sumEncoding = defaultTaggedObject { tagFieldName = "what" }使用您预先存在的字段作为标签。 -
数据声明中不需要what字段。你已经有了它的构造函数。 AESON 中的不同标签选项仅与 JSON 本身相关,与 Haskell 结构无关。因此,只需删除 what 字段即可。
-
我同意从我的结构中删除“what”字段,但是即使我添加了标签,最后一个错误
key "tag" not present又如何呢? (见编辑)