I recently starting to play with haskell and I came across a problem while using HashMap that can be illustrated by this toy example:
import Data.HashMap as HashMap
foo = HashMap.insert 42 53 HashMap.empty
Here is the error I get when I load my file in the interpreter or compile it:
Prelude List HashMap> :load TypeError.hs
[1 of 1] Compiling Main ( TypeError.hs, interpreted )
TypeError.hs:3:22:
Ambiguous type variable `k0' in the constraints:
(Num k0) arising from the literal `42' at TypeError.hs:3:22-23
(Ord k0) arising from a use of `insert' at TypeError.hs:3:7-20
(Data.Hashable.Hashable k0)
arising from a use of `insert' at TypeError.hs:3:7-20
Possible cause: the monomorphism restriction applied to the following:
foo :: Map k0 Integer (bound at TypeError.hs:3:1)
Probable fix: give these definition(s) an explicit type signature
or use -XNoMonomorphismRestriction
In the first argument of `insert', namely `42'
In the expression: insert 42 53 empty
In an equation for `foo': foo = insert 42 53 empty
Failed, modules loaded: none.
Prelude List HashMap>
However if I define the exact same function directly in the interpreter, I get no error:
Prelude List HashMap> let foo = HashMap.insert 42 53 HashMap.empty
Prelude List HashMap>
Does anyone have any clue about this?
Thanks.
The reason is that ghci uses extended default rules, while the compiler uses (by default) the defaulting rules specified in the language report:
Ambiguities in the class Num are most common, so Haskell provides another way to resolve them—with a default declaration: default (t1 , … , tn) where n ≥ 0, and each ti must be a type for which Num ti holds. In situations where an ambiguous type is discovered, an ambiguous type variable, v, is defaultable if:
The relevant rule is that per the report defaulting is only done if all involved classes are defined in a standard library, but the
Hashableconstraint on the key involves a class that doesn’t meet that requirement.Thus the compiler rejects it, because it can’t resolve the ambiguous type variable arising from the key, while ghci defaults it to
Integer, since ghci also defaults if other classes are involved.