By default GHCi has NoMonomorphismRestriction, whereas GHC has MonomorphismRestriction. Furthermore GHCi does not load the extensions of the modules that it loads. All of this can be changed with the LANGUAGE pragma or by setting the extensions inside the GHCi shell.
NoMonomorphismRestriction generally means that GHCi will try to infer the most polymorphic types and type signatures possible. While MonomorphismRestriction means GHC will try to infer the most monomorphic types and type signatures possible. An interesting
It makes sense for GHCi to have NoMonomorphismRestriction, in order to improve
the user experience of using GHCi, this way you don't have to type out as much
type signatures in GHCi, as the inference engine attempts to infer polymorphic
types. Note that the default presence of NoMonomorphismRestriction only
applies to code typed directly into the GHCi shell, any code externally loaded
(source file) by GHCi is still subject to MonomorphismRestriction by default
like as if it were directly compiled or executed with runhaskell
.
MonomorphismRestriction is useful inside GHC and in production environments for a variety of reasons. But I found an interesting problem that occurs when you don't have MonomorphismRestriction on:
(===) :: Eq a => Maybe a -> a -> Maybe a
Just l === r | l == r = Just l
_ === _ = Nothing
infixl 4 ===
result = Just 1 === Nothing
The above should be a type error. But without MonomorphismRestriction, GHC and
GHCi would not catch the type error. It's because of how 1
is inferred to be
polymorphic Num a => a
, instead of just Integer
.
To get around MonomorphismRestriction, you just have to type out your preferred type signature explicitly in the code.