I ran into a Haskell compilation error and it can be simplified to the following example:
newtype MyNewType a = MyNewType { run :: Maybe a } -- just for demo
class ExTypeClass g where
bar :: String -> g ()
instance ExTypeClass MyNewType where
bar s = MyNewType $ Just ()
-- foo :: ExTypeClass g => g ()
foo = bar "\n"
The above code causes the following error during compilation:
• Ambiguous type variable ‘g0’ arising from a use of ‘bar’
prevents the constraint ‘(ExTypeClass g0)’ from being solved.
Relevant bindings include foo :: g0 () (bound at TypeClass.hs:10:1)
Probable fix: use a type annotation to specify what ‘g0’ should be.
These potential instance exist:
instance ExTypeClass MyNewType -- Defined at TypeClass.hs:6:10
• In the expression: bar "\n"
In an equation for ‘foo’: foo = bar "\n"
If I added the foo :: ExTypeClass g => g ()
back then it works fine.
However if I remove foo = bar "\n"
, the program can compile and get loaded in GHCI
, then check bar "\n"
type in the terminal:
*Main> :t bar "\n"
bar "\n" :: ExTypeClass g => g ()
My questions are
1) Why couldn't it compile in the first place? Isn't Haskell highly polymorphic to begin with? Why do I have to specify type variable g0
anyway for it to compile? I think I don't understand something fundamentally important.
2) How come GHCI
can deduce the type but not when I wrote it in the program?
Thank you very much in advance.