实例重叠错误的原因是什么?

时间:2019-07-02 09:24:52

标签: haskell

在此示例中出现错误“ ToJSON [XYZ]的实例重叠”的原因是什么

data XYZ = XYZ Int
instance ToJSON [XYZ] where
  toJSON xs = ...

GHC显示为重叠实例:

instance ToJSON a => ToJSON [a] ...

这不是合适的情况:XYZ尚无ToJSON实例。我可以用{-# OVERLAPS #-}来解决它,但是我不明白为什么GHC无法理解[a]还没有a的{​​{1}}需要ToJSON的明确定义。我想念什么?

1 个答案:

答案 0 :(得分:4)

  

ipython nbconvert --to html Report_Camera_RelayLens.ipynb --TemplateExporter.exclude_input=True 尚无\begin{figure} \centerline{\includegraphics{Ressource/Figure_MTF_RelayLens.png}} \centering \rule{1cm}{1cm} \caption{\label{fig:example}__Distribution of MTF__} \end{figure} 实例

您自己说-没有实例。无法确保以后不会再添加该实例。在这种情况下应该发生什么?尤其是,如果一段代码还没有看到该实例,因此选择了XYZ,而另一段代码随后在上具有范围内的实例,您将得到两个可能不兼容的实例同时使用。破坏。

我认为您可能想表达ToJSON应该从未定义 ,但实际上Haskell没有类型概念是 not 一个类的实例。假设每种类型可能都是每个类的一个实例–只是也许还不可能看到该实例。

好吧,实际上可以 禁止实例的真正定义–通过使用unfulfillable superclass自己定义实例:

instance ToJSON a => ToJSON [a]

...如果尝试在任何地方为instance ToJSON XYZ调用instance Bottom => ToJSON XYZ where toJSON = no ,将导致类型错误。但是就语言而言,这个实例,它恰好是“ un-typecheckeable实例”。

所以,实例 是重叠的,即使重叠实际上可能不是可以编译的东西–但是实例解析不会尝试检查这一点,即尝试 编译它,那将很快变得非常低效,并且通常会导致相当不可预测的程序行为。 (如果您曾经使用过高级C ++模板,那么您就会明白我的意思。)

相反,实例查找始终仅与实例头相匹配,即toJSONXYZ。现在很明显,它们确实重叠。

为您的应用程序做的正确的事情可能是制作一个

[a]

如果您发现语法上有些尴尬,请注意,您可以使用[XYZ]扩展名

newtype XYZs = XYZs { getXYZs :: [XYZ] }

instance ToJSON XYZs where
  ...

然后

OverloadedLists

是合法的。