【问题标题】:Why does functor composition on an empty list return a Show error?为什么空列表上的函子组合会返回显示错误?
【发布时间】:2019-10-13 15:55:15
【问题描述】:

调用以下命令时,GHCI 会返回错误: 由于使用“print”而产生的模棱两可的类型变量“f0”、“b0”会阻止解决约束“(Show (f0 b0))”。

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

但是List的Functor实例将fmap定义为map,map的定义忽略了函数参数,如果第二个参数是[]简单地返回[]。这应该意味着无论我应用了多少 fmap 组合,我的表达式都应该简单地返回 [],并且应该通过调用 show []。那为什么我会看到错误呢?

(fmap.fmap) (+1) []

【问题讨论】:

  • 因为为了渲染它一个列表,类型约束是它应该渲染元素。实例为instance Show a => Show [a]
  • 谢谢,有道理。这是否意味着如果我要编写一个函数 functorExample :: [[Int]] -> [[Int]],其中 functorExample = (fmap.fmap) (+1),模糊类型 f0 和 a0 会被解析为有效实例即 [] 和 Int?
  • 确实,你可以试试(fmap . fmap) (+1) [] :: [[Int]],它会打印[]

标签: haskell functor


【解决方案1】:

确实,您的函数将始终返回 [],但类型类调度(发生在编译时,而不是运行时)必须基于参数的 type showShow[a] 实例要求 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 提示符下打印 []

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多