为什么“(2+2.0)”在 .hs 文件中是 Double 而在 GHCi 中是 "Fractional a => a"?

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

从 GHCi 中的 .hs 文件加载 a = 2+2.0 并执行 :t a 显示 a :: Double.

另一方面,在 GHCi 中执行 let b = 2+2.0:t b 显示 b :: Fractional a => a

您如何从这两份文件中推断出这一点?

我觉得这个官方文档几乎无法理解。

This documentation 是你想要的,我想。基本上,GHC 在 GHCi 中默认实现了与模块中不同的语言;特别是,可怕的单态性限制在模块中默认启用(根据语言),而在 GHCi 中它被禁用。单态限制是导致 GHC 为您的 a 选择单态类型的原因,而关闭它后,GHC 可以自由概括 b 的类型,从而产生您看到的多态类型。

关键是 GHCi 没有默认 b 的类型。它采用约束 2 :: Num a => a2.0 :: Fractional a => a 并将它们统一为 2 + 2.0 :: Fractional a => a。当它加载一个模块时,编译器强制每个值都有一个具体类型,因此 Fractional a 默认为 Double.