Being relatively new to Haskell, I'm trying to wrap my head around the following discrepancy (for which there is a good reason, I'm sure). Perhaps my question simply stems from a misunderstanding of GHCi, but I'll sleep better at night when I can put my doubts to rest.
Here goes. If, after binding a name, foo
, to some integral expression (simply 1
, here) in a script and compiling that script, I load the latter in GHCi, :t
tells me that the type of foo
is 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
As I understand it, the ambiguity in the type of foo
is resolved thanks to some default declaration, which, I presume, is specified somewhere in Prelude
:
default (Integer, Double)
So far, so good. However, when I carry out a seemingly equivalent let
binding directly inside GHCi, :t
tells me that the latter still treats foo
as a polymorphic numeric constant, not as an Integer
:
$ ghci
λ> let foo=1
λ> :t foo
foo :: Num a => a
How can this discrepancy be explained? What is the rationale behind it? Does GHCi not apply the default declaration to resolve type ambiguity? And if it does, in what situations does it do it?
(For information, I'm using GHC 7.8.3.)
In GHC 7.8 or greater the Monomorphism Restriction is indeed off inside the GHCi shell, so declarations at the interactive shell will not apply the Num defaulting rules to top level expressions not under a lambda binder ( per the monomorphism restriction ). The monomorphism restriction will still apply to external modules that are loaded.
You can toggle this with
:set -XMonomorphismRestriction
.