Why is “(2+2.0)” Double in a .hs file but “Fractional a => a” in GHCi?

徘徊边缘 提交于 2020-01-04 04:08:25

问题


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

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