首页 文章

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

提问于
浏览
4

我一直在得到一些奇怪的类型类错误,形式为“没有实例(测试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 回答

  • 10

    作为禁用整个文件的单态限制的替代方法(这是相当无害的,但可能会导致某些意外重新计算不是多态的值),添加类型确实有帮助,但您必须将其作为签名在顶层:

    foo :: Test a => a
    foo = test
    

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

  • 1

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

    在我的实际情况中,"constant"本身就是一个函数(通过currying) . 我现在正准备好了;我应该使用 -XNoMonomorphismRestriction ,还是添加类型声明?后者似乎不那么激烈/侵扰,但另一方面,我只是不喜欢MR对我的类型所做的事情 .

相关问题