1

我在理解 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 }

所以我认为这与打印语句有关。

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

Prelude Data.Map> print empty
fromList []

一切正常。

所以我希望有人能解释一下问题出在哪里。

提前致谢。

4

2 回答 2

7

此代码按应有的方式运行,而不会收到任何错误消息。

在源文件中,它不应该。

import qualified Data.Map as M

test = M.empty

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

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

然而,在 ghci 中,有扩展的默认规则允许默认类型。如果要打印,则对两个类型变量都引入test了进一步的约束,并且 ghci在被要求打印时默认为to的类型。ShowtestMap () ()

于 2012-07-24T14:57:01.843 回答
0

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

print另一方面,有 type print :: Show a => a -> IO (),这意味着它只能显示属于 的实例的类型Show,而M.empty有 type Map k a,则没有这样的约束。它可以是任何类型k,或者a- 不需要能够显示它们。

所以,基本上,print不知道它被要求显示什么类型。

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

于 2012-07-24T14:56:44.090 回答