5

在玩 Haskell 交互式提示 (ghci) 时,我遇到了一些我觉得很好奇的东西。以下代码在 ghci 7.0.4 下运行

[minBound..1]

抛出以下异常:

<interactive>:1:12:
    Ambiguous type variable `t0' in the constraints:
      (Num t0) arising from the literal `1' at <interactive>:1:12
      (Enum t0) arising from the arithmetic sequence `minBound .. 1'
                at <interactive>:1:1-13
      (Bounded t0) arising from a use of `minBound'
                   at <interactive>:1:2-9
    Probable fix: add a type signature that fixes these type variable(s)
    In the expression: 1
    In the expression: [minBound .. 1]
    In an equation for `it': it = [minBound .. 1]

我知道将上面的内容写为 [minBound..1 :: Int] 会清楚地表明这里的 '1' 是一个Int,但我的问题是,歧义在哪里?'1' 可以解释为IntIntegerFloatDouble,但除了Int之外,这些都不属于Bounded类。那么文字 1 是否可以伪装成另一个类?如果不是,那又如何?

4

1 回答 1

10

根据默认规则,一个受约束的类型变量会尝试通过默认来解决,如果

  • 所有约束都有形式C aa在约束中不作为类型构造函数的参数出现,并且
  • 所涉及的类中至少有一个是数字类,并且
  • 所有类都在 Prelude 或标准库中定义。

表达式的推断类型[minBound .. 1]

[minBound .. 1] :: (Num a, Enum a, Bounded a) => [a]

所以默认规则适用。但是对于默认,仅考虑模块默认声明中列出的类型- 在没有默认声明的情况下,假定默认默认(Integer, Double),即解析受约束的模糊类型变量,首先Integer尝试,如果没有t 满足所有约束,Double被尝试。如果这也不满足所有约束,则默认失败并且编译失败并出现ambiguous type variable错误¹。

在目前的情况下,既不满足Integer也不Double满足Bounded约束,因此默认失败。

¹ 在 ghci 中,或ExtendedDefaultRules启用扩展时,如果约束中没有数字类但默认值被扩展,也会尝试Show默认设置,并且默认默认值扩展为().

于 2012-04-23T20:23:32.240 回答