问题描述
数字文字具有多态类型:
Numeric literals have a polymorphic type:
*Main> :t 3
3 :: (Num t) => t
但是如果我将变量绑定到这样的文字,多态性就会丢失:
But if I bind a variable to such a literal, the polymorphism is lost:
x = 3
...
*Main> :t x
x :: Integer
另一方面,如果我定义一个函数,它当然是多态的:
If I define a function, on the other hand, it is of course polymorphic:
f x = 3
...
*Main> :t f
f :: (Num t1) => t -> t1
我可以提供一个类型签名来确保 x
保持多态:
I could provide a type signature to ensure the x
remains polymorphic:
x :: Num a => a
x = 3
...
*Main> :t x
x :: (Num a) => a
但是为什么需要这样做呢?为什么不推断多态类型?
But why is this necessary? Why isn't the polymorphic type inferred?
推荐答案
单态限制 表示所有不带参数定义且没有显式类型注释的值都应该具有单态类型.可以使用 -XNoMonomorphismRestriction
在 ghc 和 ghci 中禁用此限制.
It's the monomorphism restriction which says that all values, which are defined without parameters and don't have an explicit type annotation, should have a monomorphic type. This restriction can be disabled in ghc and ghci using -XNoMonomorphismRestriction
.
限制的原因是如果没有这个限制,long_calculation 42
将被评估两次,而大多数人可能会期望/希望它只被评估一次:
The reason for the restriction is that without this restriction long_calculation 42
would be evaluated twice, while most people would probably expect/want it to only be evaluated once:
longCalculation :: Num a => a -> a
longCalculation = ...
x = longCalculation 42
main = print $ x + x
这篇关于为什么在 Haskell 中没有推断出多态值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!