以下代码无法编译:
import Data.Bits
xor2 = xor
但是,一旦我添加了类型信息,它就会编译:
import Data.Bits
xor2 :: Bits a => a->a->a
xor2 = xor
我无法解释这一点。有什么解释吗?
答案 0 :(得分:9)
这是dreaded monomorphism restriction(MMR)的问题,默认情况下已启用。 MMR是一种规则,它强制看起来不像函数的顶级绑定(即x = ...
vs x a = ...
)具有单态绑定,除非它们具有显式的多态类型签名。
问题是Bits a => a -> a -> a
是多态的(请注意类型变量a
),而Haskell不知道如何选择满足a
的{{1}}的默认类型约束。
添加类型签名后,MMR会被缓和,您可以拥有一个多态的顶级绑定。另一个选择是" eta-expand"通过添加命名参数来定义;因为Bits
现在在语法上看起来像一个函数,MMR不适用:
xor2
您也可以使用语言扩展程序关闭MMR。您可以将它放在模块的顶部:
xor2 x = xor x