Why does GHC infer a monomorphic type here, even with MonomorphismRestriction disabled?

本小妞迷上赌 提交于 2019-12-04 00:33:58

Polymorphic recursion (where a function calls itself at a different type than the one at which it was called) always requires a type signature. The full explanation is in Section 4.4.1 of the Haskell 2010 Report:

If a variable f is defined without providing a corresponding type signature declaration, then each use of f outside its own declaration group (see Section 4.5) is treated as having the corresponding inferred, or principal type. However, to ensure that type inference is still possible, the defining occurrence, and all uses of f within its declaration group must have the same monomorphic type (from which the principal type is obtained by generalization, as described in Section 4.5.2).

The same section later presents an example of polymorphic recursion supported by a type signature.

My understanding is that unaided type inference is generally undecidable in the presence of polymorphic recursion, so Haskell doesn't even try.

In this case, the type checker starts with

w :: a

where a is a meta-variable. Since fromInteger is called with w as an argument within its own declaration (and therefore within its declaration group), the type checker unifies a with Integer. There are no variables left to generalize.

A slight modification of your program gives a different result for the same reason:

v = fromIntegral v

By your original reasoning, Haskell would infer v :: forall a. Num a => a, defaulting the v on the RHS to type Integer:

v :: forall a. Num a => a
v = fromIntegral (v :: Integer)

But instead, it starts with v :: a. Since v is passed to fromIntegral, it imposes Integral a. Finally, it generalizes a. In the end, the program turns out to be

v :: forall a. Integral a => a
v = fromIntegral (v :: a)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!