为什么这个类型类只用“-XNoMonomorphismRestriction”编译?

时间:2014-09-03 00:05:42

标签: haskell typeclass

我遇到了一些奇怪的类型类错误,形式为“没有实例(测试a0)来自表达式类型签名”。以下是我可以提出的最简单的违规代码版本:

class Test a where
  test :: a

foo = test

添加类型无济于事:

foo = test :: Test a => a

但是,添加Test实例会使其编译:

instance Test Int where
  test = 0

这是不可接受的,因为我希望我的实例在其他地方宣布。

最后,将-XNoMonomorphismRestriction传递给ghc(i)也可以编译。虽然现在已经足够好了,但我不明白这个扩展的作用是什么,为什么有必要,或潜在的缺点。

2 个答案:

答案 0 :(得分:10)

作为禁用整个文件的单态限制的替代方法(相当无害,但可能导致某些意外重新计算意图为多态的值),添加类型帮助,但你必须在顶层做一个签名:

foo :: Test a => a
foo = test

如果您在test之后添加它,它只被视为子表达式test上的注释,并且不会关闭foo本身的单态限制。

答案 1 :(得分:1)

阅读this article后,我终于理解了单形态限制。关键是看起来像常数的东西不应该是多态的,因为这可能导致它们被多次评估(最坏的情况导致指数减速)。

在我的实际案例中,"常数"本身就是一个功能(通过currying)。我现在在围栏上;我应该诉诸-XNoMonomorphismRestriction,还是添加类型声明?后者似乎不那么激烈/侵扰,但另一方面,我不喜欢MR对我的类型所做的事情。