问题
Loading a = 2+2.0
from a .hs
file in GHCi and doing :t a
shows a :: Double
.
On the other hand, doing let b = 2+2.0
and :t b
in GHCi shows b :: Fractional a => a
.
How are you able to deduce this from these two documents?
- 4.3.4 Ambiguous Types, and Defaults for Overloaded Numeric Operations https://www.haskell.org/onlinereport/haskell2010/haskellch4.html#x10-750004.3
- 2.4.8 Type defaulting in GHCi: https://downloads.haskell.org/~ghc/7.8.3/docs/html/users_guide/interactive-evaluation.html
I find this official documentation almost incomprehensible.
回答1:
This documentation is what you want, I think. Basically, GHC implements a different language by default in GHCi than in a module; in particular, the dreaded monomorphism restriction is enabled by default in a module (as per the language) whereas in GHCi it's disabled. The monomorphism restriction is what causes GHC to pick a monomorphic type for your a
, whereas, with it turned off, GHC is free to generalize the type of b
, yielding the polymorphic type you see.
回答2:
The key is that GHCi isn't defaulting the type of b
. It takes the constraints 2 :: Num a => a
and 2.0 :: Fractional a => a
and unifies them to give 2 + 2.0 :: Fractional a => a
. When it loads a module, the compiler forces every value to have a concrete type, so Fractional a
is defaulted to Double
.
来源:https://stackoverflow.com/questions/28336108/why-is-22-0-double-in-a-hs-file-but-fractional-a-a-in-ghci