| detail, of course ;). What I'm secretly hoping is that the | GHC/hugs/HBC people will see what I'm trying to achieve, tell me I'm | totally nuts, and then suggest an alternative, much simpler approach | which gives us exactly the same goal ...
As I implied earlier, I am thus far unconvinced that the complexity cost justifies the benefit. Let me suggest two simpler alternatives. Alternative 1 ~~~~~~~~ Given import FiniteMap( FM, add {- :: FM a b -> a -> b -> FM a b -} ) and fm :: FM Int Bool, you want fm.add x y to mean the same as add fm x y (but in addition allow lots of unrelated 'add' functions) My objection is that the type of 'fm' is a matter of inference, whereas in Java it'd be a matter of explicit declaration. But you could adapt your story to be more explicit, thus FM.add fm x y The qualifier here is the *type* not the *module*. (Let's assume they share a name space for now.) This would work for record selectors too: data T = T { x::Int, y::Int } data S = S { x::Int, y::Int } Now f p q = T.x p + S.y q I guess the rule is that you can qualify a function by the name of the outermost type constructor of its first argument. I would restrict this only to functions with explicitly-declared types, so that there's no interaction with inference. Alternative 2 ~~~~~~~~ If the big bug-bear is record selectors, let's focus on them exclusively. I now think that ML got it right. ML records are simply labelled tuples. So just as (Bool,Int) is an anonymous type, so is {x::Bool, y::Int}. Indeed (Bool,Int) is just shorthand for {#1::Bool, #2::Int}. In Haskell, a function with a tuple argument takes exactly that tuple: f :: (Bool,Int) -> Bool f (x,y) = x Here, f cannot take a 3-tuple or a 89-tuple. In ML it's the same with records (I'm not getting the ML syntax right, but you'll get the idea): f :: {x::Bool, y::Int} -> Bool f r = r.x Here f cannot take a record of shape other than {x::Bool,y::Int}. You are allowed to write f {x, ...} = x but you must then explain f's argument type separately. For example you can write f :: {x::Bool, p::String, q::Bool} -> Bool f {x, ...} = x So there is no sub-typing, no row polymorphism, no attempt to give f r = r.x a fancy type that makes f applicable to any record with an x field. On the other hand, there is also no problem with many records having the same field name either, which is the problem we started with. There are no implicitly-defined record selectors either: you have to use pattern matching for that. My personal view is this: we should have adopted the ML view of records. It solves the immediate problem, and no more elaborate scheme seems sufficiently "right" to be declared the winner. Alas, like all other proposals, it's not backward compatible, and hence not likely to fly. Simon _______________________________________________ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell