【问题标题】:Disambiguate the .= operator in Aeson in Haskell在 Haskell 中消除 Aeson 中的 .= 运算符的歧义
【发布时间】:2019-04-17 01:39:26
【问题描述】:

我在将对象序列化为 json 时尝试重命名键。

我理解这样做的方法是,而不是仅仅使用派生泛型,定义一个具有自定义键名的实例,如下所示:

-- instance ToJSON R2  -- old
instance ToJSON R2 where
  toJSON (R2 recCode recDate) = object [ "code" .= recCode , "date" .= recDate ]
-- new

但是,这给了我:

<interactive>:2:70: error:
    Ambiguous occurrence ‘.=’
    It could refer to either ‘Data.Aeson..=’, imported from ‘Data.Aeson’ (and originally defined in ‘aeson-1.3.1.1:Data.Aeson.Types.ToJSON’)
                          or ‘Control.Lens..=’, imported from ‘Control.Lens’ (and originally defined in ‘Control.Lens.Setter’)

我试图解决这个问题是通过在我的代码中定义 .= 运算符来明确地强制它的含义,例如:

(.=) = Data.Aeson.(.=)

这是一个猜测,但似乎是错误的语法。我通过类比将括号添加到以下资源:

这给了我这个错误:

(.=) = Data.Aeson (.=)

<interactive>:1:8: error:
    Not in scope: data constructor ‘Data.Aeson’
    No module named ‘Data’ is imported.

正确的语法是什么,“让 .= 明确地成为来自 Data.Aeson.=”?

【问题讨论】:

    标签: haskell aeson


    【解决方案1】:

    如果您可以在文件中将 .= 定义为来自 Aeson 的文件,您可以简单地从 Control.Lens 隐藏 .= 的导入:

    import Control.Lens hiding ((.=))
    

    外括号是导入隐藏列表,内括号是必需的,因为.= 是一个运算符 - 即具有非字母数字字符的名称。

    【讨论】:

      【解决方案2】:

      可以通过更仔细地阅读错误输出以查看两个句点并用括号将(整个)包围作为运算符来找到答案。这行得通

      (.=) = (Data.Aeson..=)
      

      【讨论】:

      • 这样做的问题是,如果在顶层定义,它只会增加额外的歧义。 (当然,如果在本地定义,它只会隐藏顶级定义。)不过,这个表示法可以内联使用:"code" Data.Aeson..= recCode"code" A..= recCode 给定import qualified Data.Aeson as A。尽管如此,隐藏镜头导入——或者更好的是,使用显式导入列表并从中省略(.=)——是更可取的。
      猜你喜欢
      • 2021-11-14
      • 2019-01-29
      • 2011-07-16
      • 2010-09-27
      • 1970-01-01
      • 1970-01-01
      • 2012-09-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多