Это поведение объясняется в следующем сообщении в блоге:
Вкратце: GHC достаточно умен, чтобы понять, чтоу вас есть только один экземпляр класса типов C
и вы решили, что это единственный возможный экземпляр, поэтому каждый раз, когда он видит ограничение C m
, он заменяет его на Monoid m
, поскольку они эквивалентны.
NB Как далее объясняет @chi в комментарии:
Когда GHC находит ограничение C t
, оно пытается его решить. Если if находит совпадение instance (...) => C t where ...
, ограничение заменяется контекстом (...)
. Это повторяется в максимально возможной степени. Окончательное ограничение появляется в типе (или вызывает «неразрешенную» ошибку типа). Этот процесс оправдан, поскольку может быть только один совпадающий экземпляр. Перекрывающиеся экземпляры изменяют это и предотвращают это сокращение контекста, когда несколько экземпляров (в области действия!) Приблизительно совпадают. Это хрупкое расширение, которое следует использовать с осторожностью.