为什么 Yesod 中没有 ToJSON/FromJSON 的持久类型实例?
为生成的类型编写 ToJSON/FromJSON 实例并不困难,但是,当您生成代码时,您可以将其放入吗?或者作为 Yesod 用户有没有一种简单的方法可以实现这一点? (我还没有深入研究 TH 的工作原理...)
更新: 好的,我喜欢这个建议,但是假设我的持久类型是 User。如果我使用
$(deriveJSON id ''User)
它
Exception when trying to run compile-time code:
Data.Aeson.TH.withType: Unsupported type: TySynD Model.User [] (AppT (ConT Model.UserGeneric) (ConT Database.Persist.GenericSql.Raw.SqlPersist))
Code: deriveJSON (id) 'User
显然会产生效果,因为它是一个别名。但
$(deriveJSON id ''UserGeneric)
产量
Kind mis-match
The first argument of `UserGeneric' should have kind `(* -> *)
-> *
-> *',
but `backend[i5XB]' has kind `*'
我可能仍然得到了错误的类型,但我找不到足够的关于持久生成的内容来获得正确的咒语。
It's not that hard to write ToJSON/FromJSON instances for the generated types but still, while you're generating code could you throw that in? Or is there an easy way to make this happen as a Yesod user? (I haven't dug too deep into how TH works...)
Update:
OK, I like this suggestion but, say my persistent type is User. If I use
$(deriveJSON id ''User)
it yields
Exception when trying to run compile-time code:
Data.Aeson.TH.withType: Unsupported type: TySynD Model.User [] (AppT (ConT Model.UserGeneric) (ConT Database.Persist.GenericSql.Raw.SqlPersist))
Code: deriveJSON (id) 'User
apparently because it's an alias. But
$(deriveJSON id ''UserGeneric)
yields
Kind mis-match
The first argument of `UserGeneric' should have kind `(* -> *)
-> *
-> *',
but `backend[i5XB]' has kind `*'
I've probably still got the wrong type but I can't find enough about what Persistent generates to get the right incantation.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
对于没有注意到 Michael Snowman 帖子中的子评论的人,在持久版本的新版本中,您可以执行以下操作:
并获取 Person 的 ToJSON 和 FromJSON 实例。
For anyone who doesn't notice the sub comment on Michael Snowman's post, in resent versions of persistent you can do:
and get ToJSON and FromJSON instances of Person.
事实上,我认为我们会将此功能添加到 Persistent 0.8 中(将在一两周内与 Yesod 0.10 一起发布)。 dflemstr 所说的关于依赖膨胀的说法是正确的,这就是为什么我们过去没有这样做的原因,但我们现在已经依赖 aeson 来作为我们的配置类型(基于 Yaml 配置文件,它使用 aeson 的数据类型)。
I actually think we'll be adding this feature to Persistent 0.8 (to be released with Yesod 0.10 in a week or two). It's true what dflemstr said about dependency bloat, which is why we haven't done this in the past, but we already depend on aeson now for our configuration types (based on Yaml config files, which uses aeson's data types).
您可以使用 中的自动派生机制
Data.Aeson.TH
。这应该适用于 Yesod 生成的数据类型以及您自己的类型。
它需要一个函数来自定义记录字段名称。在这里,我刚刚传递了
id
以使它们保持不变。 有关详细信息,请参阅文档 。You can just use the automatic deriving mechanism in
Data.Aeson.TH
.This should work fine on both Yesod-generated data types as well as your own types.
It takes a function to customize the record field names. Here, I've just passed
id
to get them unchanged. See the documentation for details.默认的 Yesod 类型生成器不应生成
ToJSON
/FromJSON
实例,因为这会添加对aeson
的依赖,即使您不想要使用该包,这可能会导致依赖性膨胀。您可以导入
Data.Aeson.TH
并使用此代码自动创建 JSON 实例:如果您不希望将
id
替换为为您重命名字段的函数, Haskell 中的字段名称与 JSON 文件中的字段名称相同。The default Yesod type generators shouldn't generate
ToJSON
/FromJSON
instances, because that would add a dependency onaeson
even if you didn't want to use that package, which could lead to dependency bloat.You can import
Data.Aeson.TH
and use this code to automatically create JSON instances:Replace
id
with a function that renames fields for you, if you don't want the same field names in Haskell as in the JSON file.