作为对 Haskell 来说相对较新的人,我试图围绕以下差异进行思考(我敢肯定,这是有充分理由的)。也许我的问题只是源于对GHCi的误解,但是当我可以消除疑虑时,我会在晚上睡得更好。
来了。如果在将名称foo
绑定到脚本中的某个完整表达式(此处简称1
)并编译该脚本后,我将后者加载到 GHCi 中,:t
告诉我foo
的类型是Integer
。
$ printf %s\n "foo=1" > foo.hs
$ ghci
λ> :l foo.hs
[1 of 1] Compiling Main ( foo.hs, interpreted )
Ok, modules loaded: Main.
λ> :t foo
foo :: Integer
据我了解,由于一些默认声明,foo
类型的歧义得到了解决,我认为该声明在Prelude
某处指定:
default (Integer, Double)
目前为止,一切都好。但是,当我直接在 GHCi 内部执行看似等效的let
绑定时,:t
告诉我,后者仍然将foo
视为多态数字常数,而不是Integer
:
$ ghci
λ> let foo=1
λ> :t foo
foo :: Num a => a
如何解释这种差异?其背后的理由是什么?GHCi 是否不应用默认声明来解决类型不明确性?如果是这样,它在什么情况下会这样做?
(有关信息,我使用的是 GHC 7.8.3。
ghci 是否不应用默认声明来解决类型歧义?
在 GHC 7.8 或更高版本中,单态限制确实在 GHCi 外壳中关闭,因此交互式外壳上的声明不会将 Num 默认规则应用于不在 lambda 绑定器下的顶级表达式(根据单态限制)。单态限制仍将适用于加载的外部模块。
您可以使用 :set -XMonomorphismRestriction
.