TDNR without new operators or syntax changes

Henning Thielemann lemming at henning-thielemann.de
Sun May 22 08:03:31 UTC 2016


On Sun, 22 May 2016, Jeremy . wrote:

> 1. If the compiler encounters a term f a, and there is more than one definition for f in scope (after following all of
> the usual rules for qualified imports);
> 
> 2. And exactly one of these definitions matches the type of a (or the expected type of f if given);
> 
> 3. Then this is the definition to use.


I know people are unhappy with Haskell's records and module system, but I 
still think that's because these language features are not used properly. 
Type classes are the tool to write generic code and reduce combinatoric 
explosion of functions and modules are a way to collect functions per 
type. Following this principle you give function names that make sense 
together with the module name like File.write or Channel.write. Then there 
is no need for the compiler to disambiguate unqualified identifiers and 
you keep the type and the module issues separated.

Today, if you stick to the unqualified style, and I guess you want to 
import modules without explicit identifier list, too, then your code can 
break whenever the imported modules add identifiers. In order to prevent 
this you have to use tight package import version bounds in your Cabal 
file. Your proposal would not solve this problem. Type-driven name 
resolution may disambiguate identifiers in some case but not in all ones, 
thus you still need to use tight version bounds.

The proposal seems to be a big complication. The compiler can no longer 
emit a message: "Type of function f mismatch", but it has to emit "If f 
means A.f, then the type error would be ..., but if it means B.f, then the 
type error would be ..." Or even worse: "If f means A.f and g means C.g, 
then the type error would be ... if f means B.f and g means C.g ... or f 
means A.f and g means D.g ..." The proposal also is more error-prone, 
because if you make a type-error this could be shadowed by a function in 
scope with a type that matches accidentally. A function with a very 
generic type and a generic name might be such an accidental match.

That said, the more complicated the proposals become the more one should 
reconsider about whether one runs in the right direction. I think this is 
the case here. The simple answer could be: Switch to a cleaner coding 
style!


More information about the Glasgow-haskell-users mailing list