Проблема в том, что CompNode Int не является графиком, поэтому я не думаю, что первый соответствующий экземпляр должен запускаться.
Вы могли бы подумать об этом, но, к сожалению, это не сработало.
Когда GHC выбирает экземпляр, он смотрит только на head , т.е. на часть после имени класса. Только после выбора экземпляра он проверяет контекст , то есть часть перед =>
. Несоответствия в контексте могут вызвать отклонение экземпляра и привести к ошибке проверки типа, но они не приведут к тому, что GHC будет возвращаться и искать другой экземпляр.
Итак, учитывая эти случаи:
instance (G.Graph g, PrettyShow (G.Vertex g)) => PrettyShow g
instance (PrettyShow a, Show a) => PrettyShow (CompNode a)
... если мы игнорируем контекст, они выглядят так:
instance PrettyShow g
instance PrettyShow (CompNode a)
Что должно прояснить, что первый экземпляр является полностью общим и перекрывает абсолютно все.
В некоторых случаях вы можете использовать расширение OverlappingInstances
, но это не меняет вышеуказанное поведение; скорее, это позволяет GHC разрешать неоднозначные случаи, выбирая уникально наиболее конкретный случай, если таковой существует. Но использование перекрывающихся экземпляров может быть сложным и привести к загадочным ошибкам, поэтому я рекомендую вам сначала переосмыслить дизайн и посмотреть, сможете ли вы полностью избежать этой проблемы.
Тем не менее, в данном конкретном примере CompNode a
действительно является однозначно более конкретным совпадением для CompNode Int
, поэтому GHC выберет его вместо общего экземпляра.