Type checking question

Rijk-Jan van Haaften rjchaaft@cs.uu.nl
Fri, 02 Nov 2001 17:46:34 +0100


Adrian wrote:
>textNew (creates a new text widget) has type:
>textNew :: AdjustmentClass adj => Maybe adj -> Maybe adj -> IO Text
>But when I try to create one using:
>         txt <- textNew Nothing Nothing
>GHC complains:
>     Ambiguous type variable(s) `a'
>         in the constraint `GtkAdjustment.AdjustmentClass a'
>     arising from use of `textNew' at Main.hs:82
>     in a `do' expression pattern binding:
>         txt <- textNew Nothing Nothing
>My first thought was that I need a type signature for txt,
>but seeing as txt has to be type IO Text, I dont think
>that's possible (because 'adj' is not referenced).
>Is that correct?

The problem is that GHC can not find out (From the two Nothing objects)
which instance of AdjustmentClass to use. Different instances might lead
to different "IO Text" objects, so choosing a default is impossible.
For example:
show ([] :: [Int])  == "[]"
show ([] :: [Char]) == "\"\""

Therefore, you have to tell GHC the exact type of "textNew Nothing Nothing"
with a type annotation, just like in the examples with show above:

txt <- textNew (Nothing :: Maybe SomeDefaultAdjustmentClass) Nothing

In this case, supplying the type of one of the two Nothing values is
enough (GHC can find out the other one must be the same).

>So, what should one do in this situation?
>Something like this perhaps..
>  myNothing :: Maybe dummyAdjustmentClassInstance
>  myNothing = Nothing
>  txt <- textNew myNothing myNothing
>I'm pretty sure that would do it, but it seems like
>an ugly solution. Is there a better way?

This is indeed one solution. This way, you tell GHC a dummy
instance is possible; unlike the show-situation where it is

Using type annotations is another solution, but it is not
as comfortable if you are supplying textNew often with just
twice Nothing. If it's just a few cases, I prefer this option.

As a last alternative, only useful if you use
"textNew Nothing Nothing" often, is to write a
special function for this case (in all other
cases, GHC can infer the right type so we don't
need a special function):

textNewNothing = textNew (Nothing :: Maybe SomeDefaultAdjustmentClass) Nothing