为什么 Haskell 中不推断多态值?
数字文字具有多态类型:
*Main> :t 3
3 :: (Num t) => t
但是,如果我将变量绑定到这样的文字,则多态性就会丢失:
x = 3
...
*Main> :t x
x :: Integer
另一方面,如果我定义一个函数,它当然是多态的:
f x = 3
...
*Main> :t f
f :: (Num t1) => t -> t1
我可以提供类型签名来确保 < code>x 仍然是多态的:
x :: Num a => a
x = 3
...
*Main> :t x
x :: (Num a) => a
但是为什么这是必要的呢?为什么不推断多态类型?
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
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是单态限制,它表示所有不带参数定义的值并且不具有显式类型注释应该具有单态类型。可以使用
-XNoMonomorphismRestriction
在 ghc 和 ghci 中禁用此限制。限制的原因是,如果没有此限制,
long_calculation 42
将被评估两次,而大多数人可能期望/希望它只被评估一次: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
.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:稍微扩展一下 sepp2k 的答案:如果您尝试编译以下内容(或将其加载到 GHCi 中),则会收到错误:
这违反了单态性限制,因为我们有一个类约束(由
sort< 引入) /code>),但没有明确的参数:我们(有点神秘地)被告知,在约束
Ord a
中有一个不明确的类型变量
。您的示例 (
let x = 3
) 具有类似的不明确类型变量,但它不会给出相同的错误,因为它是由 Haskell 的“默认”规则:有关默认规则的更多信息,请参阅此答案 - 重要的一点是它们仅适用于某些数字类,因此 x = 3 可以,而 f = sort 则不行。
附带说明:如果您希望
x = 3
最终成为Int
而不是Integer
,并且y = 3.0
是一个Rational
而不是Double
,您可以使用“默认声明”来覆盖默认的默认规则:To expand on sepp2k's answer a bit: if you try to compile the following (or load it into GHCi), you get an error:
This is a violation of the monomorphism restriction because we have a class constraint (introduced by
sort
) but no explicit arguments: we're (somewhat mysteriously) told that we have anAmbiguous type variable
in the constraintOrd a
.Your example (
let x = 3
) has a similarly ambiguous type variable, but it doesn't give the same error, because it's saved by Haskell's "defaulting" rules:See this answer for more information about the defaulting rules—the important point is that they only work for certain numeric classes, so
x = 3
is fine whilef = sort
isn't.As a side note: if you'd prefer that
x = 3
end up being anInt
instead of anInteger
, andy = 3.0
be aRational
instead of aDouble
, you can use a "default declaration" to override the default defaulting rules: