【问题标题】:Why aren't Persistent types instances of ToJSON/FromJSON in Yesod?为什么 Yesod 中没有 ToJSON/FromJSON 的 Persistent 类型实例?
【发布时间】:2013-12-08 20:44:11
【问题描述】:

为生成的类型编写 ToJSON/FromJSON 实例并不难,但是,当您生成代码时,您能把它扔进去吗?或者作为 Yesod 用户,有没有一种简单的方法可以实现这一点? (我还没有深入研究 TH 的工作原理……)

更新: 好的,我喜欢这个建议,但是,假设我的持久类型是用户。如果我使用

$(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 `*'

我可能仍然输入了错误的类型,但我找不到足够的关于 Persistent 生成的内容来获得正确的咒语。

【问题讨论】:

  • 你想明白了吗?在这里遇到完全相同的问题。
  • 我已经有一段时间没有使用 Yesod 了,但我很确定我使用 Michael Snoyman 的链接中提到的添加的“json”进行了这项工作:github.com/yesodweb/yesod/wiki/…

标签: haskell yesod aeson


【解决方案1】:

对于没有注意到 Michael Snowman 帖子的子评论的任何人,您可以在新版本的persistent 中执行以下操作:

Person json
    name Text
    age Int

并获取 Person 的 ToJSON 和 FromJSON 实例。

【讨论】:

    【解决方案2】:

    我实际上认为我们会将此功能添加到 Persistent 0.8(将在一两周内与 Yesod 0.10 一起发布)。 dflemstr 所说的依赖膨胀是真的,这就是为什么我们过去没有这样做的原因,但我们现在已经依赖 aeson 作为我们的配置类型(基于 Yaml 配置文件,它使用 aeson 的数据类型)。

    【讨论】:

    • 谢谢迈克尔,听起来不错。同时,如果有人知道deriveJSON 调用的正确语法,那也会很有帮助!
    • 这个已经实现了一段时间,见:github.com/yesodweb/yesod/wiki/…
    • 谢谢迈克尔!这是很棒的东西。如果您更新了书中关于 RESTful 内容的在线章节以包含这一事实,那就太好了。我正在使用纸质副本,但出于这个原因,我在网上查看了所有示例。
    【解决方案3】:

    您可以使用Data.Aeson.TH中的自动派生机制。

    {-# LANGUAGE TemplateHaskell #-}
    $(deriveJSON id ''Foo)
    

    这应该适用于 Yesod 生成的数据类型以及您自己的类型。

    需要一个自定义记录字段名称的函数。在这里,我刚刚通过id 以使它们保持不变。 See the documentation for details.

    【讨论】:

    • 谢谢,看来你们俩同时有相同的答案。虽然 Yesod 类型是别名,但它会生成“不支持的类型”错误。我尝试在我的类型是用户的情况下使用 $(deriveJSON id ''UserGeneric),结果如下: Kind mis-match The first argument of UserGeneric' should have kind (* -> ) -> * -> *', but @ 987654327@'
    【解决方案4】:

    默认 Yesod 类型生成器不应生成 ToJSON/FromJSON 实例,因为即使您不想使用该包,这也会增加对 aeson 的依赖,这可能导致依赖膨胀。

    您可以导入 Data.Aeson.TH 并使用此代码自动创建 JSON 实例:

    data MyDataType = ...
    
    deriveJSON id ''MyDataType
    

    如果您不希望 Haskell 中的字段名称与 JSON 文件中的字段名称相同,请将 id 替换为为您重命名字段的函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-08
      • 1970-01-01
      • 2012-07-28
      • 2023-02-08
      • 1970-01-01
      • 1970-01-01
      • 2015-03-23
      相关资源
      最近更新 更多