为什么空列表 return 上的仿函数组合会出现显示错误?

Why does functor composition on an empty list return a Show error?

调用以下内容时,GHCI return出现错误: 因使用“print”而产生的模糊类型变量“f0”、“b0”阻止了约束“(Show (f0 b0))”的求解。

据我了解,这是因为我的表达式类型是 (Num b, Functor f) => [f b] 其中 f 是不明确的类型。

然而,List的Functor实例将fmap定义为map,而map的定义忽略了函数参数,以防第二个参数是[]到简单的return[]。这应该意味着我的表达式应该只是 return [] 而不管我应用了多少 fmap 组合,并且应该通过对 show [] 的调用。为什么我会看到错误?

(fmap.fmap) (+1) []

你的函数确实总是 return [],但是类型类分派(发生在编译时,而不是 运行 时)必须基于 show 参数的类型 [a]Show 实例要求 Show a 也被解析(instance Show a => Show [a])---因为有许多 [a] 类型的值确实包含元素- --并且由于列表元素的 type(全部为 0)不明确,因此无法解析 Show 约束。

这可能会让您问为什么 show [] 没有同样的问题,因为 [] :: [a]。这里的答案是 GHCi 有一些特殊的 Extended Default Rules 启发式方法,适用于某些简单的情况,以使在提示符下工作更加愉快。如果你 :set -XNoExtendedDefaultRules 你可以看到 show [] 会有同样的行为。在您的情况下,由于列表的元素类型是 f0 b0 而不是单一类型变量,因此链接的扩展默认规则不适用,因此列表元素类型仍然包含不明确的类型变量。

您可以通过自己解决一些类型约束(例如使用 -XTypeApplications)来了解这就是问题所在。即使解决 Functor 约束也足以使正常的 Haskell 类型默认规则再次应用:(fmap.(fmap @[])) (+1) [] 确实在 GHCi 提示符下打印 []