在此示例中出现错误“ 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
的明确定义。我想念什么?
答案 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 ++模板,那么您就会明白我的意思。)
相反,实例查找始终仅与实例头相匹配,即toJSON
与XYZ
。现在很明显,它们确实重叠。
为您的应用程序做的正确的事情可能是制作一个
[a]
如果您发现语法上有些尴尬,请注意,您可以使用[XYZ]
扩展名
newtype XYZs = XYZs { getXYZs :: [XYZ] }
instance ToJSON XYZs where
...
然后
OverloadedLists
是合法的。