以下代码无法编译:
import Data.Bits
xor2 = xor
但是,一旦我添加了类型信息,它就会编译:
import Data.Bits
xor2 :: Bits a => a->a->a
xor2 = xor
我无法解释这一点。有什么解释吗?
最佳答案
这是默认情况下启用的dreaded monomorphism restriction(MMR)的问题。 MMR是一个规则,除非看起来像函数(即x = ...
与x a = ...
)的顶级绑定具有明确的多态类型签名,否则它们将强制具有单态绑定。
问题是Bits a => a -> a -> a
是多态的(请注意类型变量a
),Haskell不知道如何为a
选择满足Bits
约束的默认类型。
添加类型签名后,即可使用MMR,并且可以具有多态的顶级绑定。另一种选择是通过添加命名参数来“扩展”定义。由于xor2
现在在语法上看起来像一个函数,因此MMR不适用:
xor2 x = xor x
您也可以使用语言扩展名关闭MMR。您可以将其放在模块顶部:
{-# LANGUAGE NoMonomorphismRestriction #-}