This is an example of the common friction between typeclass function resolution and "direct" function resolution. There are many times to support the direct, as you pointed out here, but often, when you can specify the specific laws that an instance of typeclass must support, people find it worthwhile to have class permission.
I donβt think itβs possible to have a βcorrectβ answer, which is better, but there are big arguments for using the direct method more often.
In this case, more specific specifications are required to help the compiler understand which instance should be allowed. Although the case where any Monoid can have an instance of "count and comb" Measured , it is not clear that this is a canonical instance. Since the class for Measured requires Measured va | a -> v Measured va | a -> v we canonically chose v .
The most likely way to do this is to create a newtype wrapper
newtype Counted a = Counted a instance Monoid a => Measured (Sum Int, a) (Counted a) where measure (Counted x) = (Sum 1, x)
which gives us the required canonicity. This may be more convenient in some cases than directly passing the dictionary of Monoid functions.
source share