The problem is that CompNode Int is not a graph, so I don't think that the first matching instance should start.
You would think so, but, unfortunately, this does not work.
When the GHC selects an instance, it looks only at the head, i.e. to the part after the class name. Only after selecting an instance does it check the context, i.e. Part before => . Inconsistencies in the context can cause the instance to be rejected and result in type checking errors, but they will not lead to the GHC failing and looking for another instance.
So, given these instances:
instance (G.Graph g, PrettyShow (G.Vertex g)) => PrettyShow g instance (PrettyShow a, Show a) => PrettyShow (CompNode a)
... if we ignore the context, they look like this:
instance PrettyShow g instance PrettyShow (CompNode a)
What should make it clear that the first instance is completely common and covers absolutely everything.
In some cases, you can use the OverlappingInstances extension, but this will not change the behavior above; rather, it allows the GHC to resolve ambiguous instances, choosing uniquely the most specific, if any. But using matching instances can be tricky and lead to cryptic errors, so I would advise you to rethink the design first and see if you can completely fix the problem.
However, in the specific example here, CompNode a indeed a uniquely more specific match for CompNode Int , so the GHC will select it instead of the generic instance.