OK - let's get operational! Dave's choices are:
1) Build the resolution dictionary using the context of Module Two
(the point of declaration)
2) Build the resolution dictionary using the context of Module Three
(the point of use).
While Dave is on the right track, neither of these choices really
distinguishes the act of building a dictionary from referring to a
dictionary.
In terms of dictionary conversion, there are two different
dictionaries to resolve the overloading - one built in module Two and the
other in Three. The key is that when an overloaded type variable is
instanitaited to a concrete type, a dictionary is inserted into the
code. Without the type signature, the type variable which denotes the
argument to trouble in module Two is not instantiated and the
dictionary becomes a parameter - in other words, although module Two
has a dictionary constructed for Problematic(Int), since the
overloading has not been resolved this dictionary is ignored and the
trouble function will carry a dictionary parameter. At the use point
in Three, this overloaded type is instantiated to Int and the
dictionary constructed in Three is passed into trouble.
With the type signature added, module Two instantiates the overloaded
argument to trouble and the dictionary available in module Two is
used. Th this case trouble does NOT carry a dictionary parameter to
be instantiated by the call in Three.
Disclaimer: don't try this at home! This is NOT legal Haskell - real
Haskell will complain loudly if the instance declaration is not in the
same module as the Class or Data declaration. Two instances for the
same class - type combination is not possible.
As for Gofer, it does not have a C - T rule since it does not have
modules. Although Gofer allows instances to be attached to more
complex types than Haskell, it does not allow anything like Phil's
example. The one thing you can do in Gofer is add instances for
classes and types in it's Prelude tha do not already have an instance.
Thus Mark's Num(a,b) instance works fine there.
John