为什么在 Haskell 中没有推断出多态值? [英] Why are polymorphic values not inferred in Haskell?

查看:25
本文介绍了为什么在 Haskell 中没有推断出多态值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

数字文字具有多态类型:

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 中没有推断出多态值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆