对于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
类型的含糊不清是由于某些default declaration,我认为这是Prelude
中指定的地方:
default (Integer, Double)
到目前为止,这么好。但是,当我在GHCi中直接执行看似等效的let
绑定时,:t
告诉我后者仍然将foo
视为多态数字常量,不作为Integer
:
$ ghci
λ> let foo=1
λ> :t foo
foo :: Num a => a
如何解释这种差异?它背后的理由是什么? GHCi是否不应用default declaration来解决类型歧义?如果确实如此,在什么情况下呢?
(有关信息,我使用的是GHC 7.8.3。)
答案 0 :(得分:4)
ghci是否不应用默认声明来解决类型歧义?
在GHC 7.8或更高版本中,Monomorphism Restriction确实在GHCi shell内部关闭,因此交互式shell中的声明不会将Num默认规则应用于不在lambda绑定器下的顶级表达式(根据单态限制) 。单态限制仍将适用于已加载的外部模块。
您可以使用:set -XMonomorphismRestriction
切换此内容。