Haskell 中的别名函数
Aliasing function in Haskell
以下代码无法编译:
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 将得到缓解,您可以拥有多态的顶级绑定。另一种选择是通过添加命名参数来 "eta-expand" 定义;因为 xor2
现在在语法上看起来像一个函数,所以 MMR 不适用:
xor2 x = xor x
您也可以使用语言扩展关闭 MMR。您可以将其放在模块的顶部:
{-# LANGUAGE NoMonomorphismRestriction #-}
以下代码无法编译:
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 将得到缓解,您可以拥有多态的顶级绑定。另一种选择是通过添加命名参数来 "eta-expand" 定义;因为 xor2
现在在语法上看起来像一个函数,所以 MMR 不适用:
xor2 x = xor x
您也可以使用语言扩展关闭 MMR。您可以将其放在模块的顶部:
{-# LANGUAGE NoMonomorphismRestriction #-}