haskell - 合格导入后的“模糊类型变量”

时间:2012-07-24 14:42:30

标签: haskell import functional-programming qualified

我有一点问题是要理解haskell中的错误信息。

例如:

import qualified Data.Map as M

test = M.empty

此代码在不收到任何错误消息的情况下运行。

输出如下:

*Main> test

fromList []

但如果我尝试那样的话

import qualified Data.Map as M

test = do print M.empty

我收到类似这样的错误消息

Ambiguous type variable `k0' in the constraint:
      (Show k0) arising from a use of `print'
    Probable fix: add a type signature that fixes these type variable(s)
    In a stmt of a 'do' block: print M.empty
    In the expression: do { print M.empty }
    In an equation for `test': test = do { print M.empty }

所以我认为它与print语句有关。

但是如果我在控制台(ghci)中尝试它

Prelude Data.Map> print empty
fromList []

一切正常。

所以我希望有人能解释我的问题所在。

提前致谢。

2 个答案:

答案 0 :(得分:7)

  

此代码在不收到任何错误消息的情况下运行。

在源文件中,它不应该。

import qualified Data.Map as M

test = M.empty

test的推断类型是Ord k => Map k a,是具有约束类型变量的多态类型。由于test不是函数且没有类型签名,因此monomorphism restriction必须通过将约束类型变量解析为默认类型来使其类型为单形。由于这里唯一的约束是Orddefaulting rules禁止该类型变量被默认(必须至少有一个数字约束才能允许默认)。

因此,语言标准要求编译失败。

然而,在ghci中,有一些扩展的默认规则允许默认类型。如果要打印test,则会在两个类型变量上引入进一步的Show约束,并且当要求打印时,ghci会将test的类型默认为Map () ()。< / p>

答案 1 :(得分:0)

这是因为Data.Map.empty的类型为Map k a。类型为k的键的映射到值a

另一方面,

print的类型为print :: Show a => a -> IO (),这意味着它只能显示Show个实例的类型,而M.empty的类型为Map k a没有这样的约束。它可以是任何类型ka - 不需要能够显示它们。

因此,基本上,print不知道要求显示的类型。

至于为什么它在ghci中起作用;我不完全确定。也许其中一位常驻的Haskell巫师可以对此有所了解。