[Haskell-cafe] Ambiguous type variable

Daniel Fischer daniel.is.fischer at web.de
Fri Oct 15 19:39:28 EDT 2010


On Saturday 16 October 2010 01:18:55, Jacek Generowicz wrote:
> On 2010 Oct 16, at 01:14, Jacek Generowicz wrote:
> > On 2010 Oct 16, at 00:51, Ivan Lazar Miljenovic wrote:
> >> "2" is a generic number.  If you don't specify a type, it usually
> >> defaults to Integer.  All Num instances that come in the Prelude have
> >> Show instances, so no matter which gets picked "show 2" works.
> >> However, when you say "view 2" ghc/ghci doesn't know that you want 2
> >> to be an Int (as that's the only type you have an instance for View
> >> for).
> >
> > On 2010 Oct 16, at 00:51, Christopher Done wrote:
> >> Don't integral literals default to Integer, of which there is a Show
> >> instance but no View instance?
>
> An in both of the explanations above, it should then complain about
> the lack of an instance of View, rather than about ambiguous type
> variables, n'est-ce pas?

Non.

If you write

x = view 2

the type checker looks at the expression 2 and it sees it has the type

Num a => a

(because integer literals are actually shorthand for (fromInteger literal) 
and fromInteger :: Num a => Integer -> a).

Then (or before that) it looks at the context in which the 2 appears.
That context is that the function view is applied to it.

view :: View v => v -> String

So, in order for the expression 2 to be well typed, the type checker finds 
the two constraints

2 :: Num a => a
2 :: View v => v

These constraints have to be unified (which is very easy here), resulting 
in

2 :: (Num a, View a) => a

But there's no way to find out what type a is/has to be.
Hence a is an ambiguous type variable.

Now, under certain circumstances such ambiguous type variables are resolved 
by defaulting. If you replace view with show, you get a Show constraint 
instead of the View constraint and then defaulting may (and must) happen.
But since View is defined outside the standard libraries, the language 
report says defaulting mustn't take place, so it doesn't (it may work if 
you specify
{-# LANGUAGE ExtendedDefaultRules #-}
at the top of your module).


More information about the Haskell-Cafe mailing list