gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-05 02:11:55 24 4
gpt4 key购买 nike

此示例中出现“Overlapping instances for ToJSON [XYZ]”错误的原因是什么:

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

GHC 显示为重叠实例:

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

这不是一个合适的案例:XYZ 还没有 ToJSON 实例。我可以用 {-# OVERLAPS #-} 修复它,但我不明白为什么 GHC 不理解 [a] where a没有 ToJSON 需要为 ToJSON 显式定义。我想念什么?

最佳答案

XYZ has not ToJSON instance yet

你自己说的——还没有实例。无法确定以后是否有人会添加该实例。在这种情况下应该发生什么?特别是,如果一段代码还没有看到该实例,因此选择了 instance ToJSON a => ToJSON [a],而另一段代码稍后该实例在范围内,您会同时使用两个可能不兼容的实例。浩劫。

我想你可能想表达 instance ToJSON XYZ should never be defined,但实际上 Haskell 没有类型的概念 not一个类的实例。假设每种类型都是潜在每个类的实例——只是可能还看到实例。

好吧,实际上可以禁止一个实例被真正定义——通过你自己定义它,用unfulfillable superclass :

instance Bottom => ToJSON XYZ where
toJSON = no

...如果您尝试在任何地方为 XYZ 调用 toJSON,这将导致类型错误。但是,就语言而言,这一个实例,它恰好是一个“无法检查类型的实例”。

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

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

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

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

instance ToJSON XYZs where
...

如果您发现语法上很别扭,请注意您可以使用 OverloadedLists 扩展

import GHC.Exts (IsList(..))

instance IsList XYZs where
type Item XYZs = XYZ
fromList = XYZs
toList = getXYZs

然后

{-# LANGUAGE OverloadedLists #-}
test :: XYZs
test = [XYZ 1, XYZ 2]

是合法的。

关于haskell - 重叠实例错误的原因是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56849254/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com