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