Continuing the discussion from GHC2024 – community input:
I thought I should elaborate on why I think the error messages of DerivingVia
are bad, so here I go.
The error messages are bad because they mention coercion of class methods. This has a practical disadvantage: classes may have many methods, so this can cause a flood of error messages. For example consider this code:
newtype OrdList a = OrdList [a]
deriving (Functor, Foldable) via Maybe
This produces 19 error messages. That’s insane! For anyone who did not notice, the issue here is quite simple and GHC will tell you (19 times):
• Couldn't match representation of type: [a]
with that of: Maybe a
This shouldn’t be repeated 19 times.
I suspect this choice has been made because there is a case where individual methods do matter. Let’s say we correct the above mistake, but also derive Traversable
:
newtype OrdList a = OrdList [a]
deriving (Functor, Foldable, Traversable) via []
You may think nothing is wrong, but this still produces 4 error messages. That is because Traversable
has some tricky methods like traverse
. Let’s consider what the two instantiations of this method would look like:
traverse @[] :: Applicative f => (a -> f b) -> [a] -> f [b]
traverse @OrdList :: Applicative f => (a -> f b) -> OrdList a -> f (OrdList b)
Coercing between these requires coercing between f [b]
and f (OrdList b)
but this is only possible if the first parameter of f
has a phantom or representational role, but f
is a variable, so we can’t know that for sure at compile time. If you can endure the deluge of error messages then you might notice that they do mention this:
NB: We cannot know what roles the parameters to ‘f’ have;
we must assume that the role is nominal
But note that now the error isn’t specific to the []
and OrdList
instances at all. Any two different instances will fail on this method. So I would propose to report just a single error message saying that Traversable
can never be derived via anything.
I think these two cases are the only possible errors, but even if that’s not the case I think it would be very useful to add special cases for these two errors.