
AND PLEASE not the way an [existing proposal] suggests to do it! Please let's just do ad-hoc overloading. There is no reason to introduce new syntax, because syntax is completely orthogonal to this problem.
[existing proposal]: https://prime.haskell.org/wiki/TypeDirectedNameResolution
How would you propose to do TDNR instead, then? It's far from clear (to me at least) how to combine ad-hoc type-based overloading with Haskell's type inference, which is part of the reason why TDNR proposals have never been implemented.
There are two basic questions that need to be answered:
1. When does an identifier get special treatment, as opposed to the usual name resolution process?
My proposal is *always*: ...
2. At what point during type inference does an ambiguous name get resolved, and what impact does that have on the type inference process?
... type inference would have to be done multiple times, once for each matching identifier in scope. Do each of them independently, then see which ones turn out to be well-typed (no ambiguity, no missing instances, no mismatch, etc.). If there is exactly one, take it, otherwise give up with a type error. For regular unique identifiers nothing would change, so this is a backward-compatible extension.
The OverloadedLabels answer to question 1 is that special identifiers get a syntactic cue (the prefix hash). It's ugly, but it's obvious that something special is happening. Similarly, the TDNR proposal uses the dot. We could say that any ambiguous identifier (i.e. one that would cause a name resolution error at present) gets special treatment, but that's rather implicit and leads to odd changes in type inference behaviour if a colliding name is brought into or removed from scope.
My point is that that's inevitable. 1. nice syntax, 2. simple semantics, 3. no inference interference -- pick two. In today's Haskell we have 2 and 3, but we lack 1, because we need to prefix our identifiers or use qualified imports. OverloadedLabels seems to go with 1 and 3, lacking 2, because of the heavy type-level machinery it relies on. I propose that we go with 1 and 2 instead. This can of course cause problems with applications that don't fully saturate a function. Since that's common in Haskell, we would have to use it sparingly, potentially only for record fields or lenses. But that's also the primary use case, so I'd be fine with that. Greets ertes