在玩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'解释为 Int 整数 Float Double ,但 Int r除外,这些都不属于有界的ojit。那么,还有另外一个类,字面1可以伪装成吗?如果没有,那又如何呢?

最佳答案

对于defaulting rules,默认情况下将尝试解析受约束的类型变量,如果

  • 所有约束都具有C a的形式; a在约束中未显示为类型构造函数的参数,而
  • 涉及的至少一个类是数字类,而
  • 所有类都在Prelude或标准库中定义。

  • 表达式[minBound .. 1]的推断类型为
    [minBound .. 1] :: (Num a, Enum a, Bounded a) => [a]
    

    因此适用默认规则。但是对于默认设置,仅考虑模块默认声明中列出的类型-在没有默认声明的情况下,假定使用默认的(Integer, Double)默认值,即要解析受约束的歧义类型变量,请尝试使用第一个Integer,如果不能满足所有约束条件,请尝试Double。如果这也不能满足所有约束条件,则默认设置将失败,并且编译会失败,并出现ambiguous type variable错误¹。

    在当前情况下,IntegerDouble都不满足Bounded约束,因此默认设置失败。

    ¹在ghci中,或在启用ExtendedDefaultRules扩展名的情况下,如果约束中没有数字类,但Show属于数字类,则也会尝试使用默认值,并且默认默认值由()扩展。

    关于haskell - 用数字输入歧义,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10287510/

    10-11 22:29
    查看更多