One could then simply disallow the use of `HasField "slot" b a` in the domain of functions (pretty sure it can never appear in the range). This would then require the programmer to provide annotations if a more concrete type can't be inferred.
It can appear in the range (making up assignment syntax here)
foo :: (Num a, HasField "slot" a b) => b -> b
foo x = x.slot <~ 1
Technically, depending upon the semantics of records (how anonymous they are) it could even be that the input argument has a different type as the output argument, e.g.
foo {} ==> {slot = 1}
Anyway, there's a lot to be said here but I think that this isn't merely a syntactic difference. Even the idea that
map (\x -> x.slot) listOfFoos
could be inferred would require mixing type inference and syntax de-sugaring.
Should have said "if it can't appear in the domain, it can't appear in the range". Obviously if it appears in the domain it can also get into the range - a simpler example with real syntax is \x -> x.
What I'm arguing is that anonymous records are unnecessary and it's silly to insist that problems with anonymous records should derail a good solution for concrete ones. But you are right that it's a bit more than just syntactic.
One could then simply disallow the use of `HasField "slot" b a` in the domain of functions (pretty sure it can never appear in the range). This would then require the programmer to provide annotations if a more concrete type can't be inferred.