Я могу понять, что он думает, что тип a
может либо получить Show
, либо получить ListContainer
, что может привести к Show
.
Это не то, чтоон думает.
Когда Haskell выбирает экземпляр класса, он вообще не смотрит на ограничения экземпляра.Все, что он учитывает при выборе экземпляра, это заголовок экземпляра (вещь, которая идет сразу после имени класса).
В вашем экземпляре Show
заголовок экземпляра равен l a
.Эта голова экземпляра соответствует A a
(при условии l = A
).Кстати, он также соответствует многим другим вещам - например, он соответствует Maybe a
(где l = Maybe
) и Either b a
(с l = Either b
), Identity a
и IO a
- в значительной степеникаждый тип с параметром типа, если подумать.Неважно, что ни A
, ни Maybe
, ни IO
не имеют экземпляра ListContainer
, потому что, как я сказал выше, Haskell не смотрит на ограничения при выборе экземпляров, только на заголовки экземпляров.
Только после поиска подходящего экземпляра (путем сопоставления по его голове) Haskell проверит, действительно ли ограничения этого экземпляра удовлетворены.И будет жаловаться, если они не.Но он никогда не вернется и не попытается выбрать другой экземпляр.
Итак, возвращаясь к вашему примеру: теперь у A
есть два совпадающих экземпляра Show
- его собственный производный и один Show (l a)
.что вы написали, - компилятор жалуется, что они перекрываются.