I do not know the Word of God, but here are a few arguments.
No longer defines a function in the same module. Now you can write
(==) = internalIntEq (==) = internalFloatEq
This makes the code less readable. There is a sentence called "TypeBasedNameResolution" that does something similar, but the important fact is that such type branching is performed only for (==) from different modules.
It's a good practice to add a compiler to identifiers. In your case, you automatically create a class of type SupportsEqualsEquals . A new user may ask "where does this come from" and there will be no corresponding source identifying it.
Skipping an instance signature record does not give you as much as you might think. You can get the necessary parameters, for example. :t internalIntEq in ghci. I suppose this would be more convenient, but I would prefer to have a tool that could ask "what is the instance type for Eq , where == is internalIntEq .".
More complex class functions are unclear. Where do you put related types and functional dependencies? This is really important to me!
Your default complicates the assembly of the module. You will not receive free classes for free. Consider
f :: Supports[==] a => a -> a -> Bool f = (/=)
As I understand it, it comes down to
f :: Instance (Supports[==]) a -> a -> a -> Bool f eq_inst xy = not (x eq_inst.== y)
Now, if I provide a new instance of /= for a specific type a_0 and pass some x :: a_0 to f , then
fxx = not (x == x) -- computation you really want: fxx = x /= x, using the new /= instance for a_0
You may ask: "When would it be so foolish to limit f to Supports[==] instead of Supports[/=] ?" But contexts can come from more than function signatures; they can come from functions of a higher order, etc. etc.
Hope this helps.