
| the concrete proposal is to address one of these remaining issues, | namely how to identify record field labels as such. for that, I | outlined three options, although that outline perhaps wasn't concrete | enough: | | 1. make label declarations unneccessary (eg., #pointX :: #PointX) effect on the type system: a new (meta-)rule for a new kind of literal constants: whenever we see something looking like " '#'<identifier> ", its type is " '#'<Identifier>". Essentially the same as for other literals: whenever we see something looking like " [0-9]+ ", its type is " Num a => a ". whenever we see " True ", its type is " Bool ", etc. . Similar to numeric literals, there'd be no place in source where all those literals/labels are declared, but literals of the same type in different modules would be compatible. So this would work without problems: module A main = #pointX module B main = #pointX module C import A import B main = print [A.main,B.main] | 2. make type sharing expressible (something like the sharing | constraints in Standard ML's module language, to allow you to | say when two declarations from different imports refer to the | same type) this is definitely a type system issue. if we have module A where data PointX = PointX deriving Show main = print PointX module B where data PointX = PointX deriving Show main = print PointX module C -- this doesn't work! import A import B main = print PointX -- conflict here! ambiguous occurrence.. we have a problem. in a simple form, the sharing constraints I had in mind would permit us to express which structurally equivalent declarations define *the same type*. that is, module C would be module C import A import B sharing A.PointX B.PointX main = print PointX -- no conflict, A.PointX and B.PointX have been -- identified, refer to the same type the type system would need to unify the shared types. to make that safe, it would need to check for structural equivalence of the declarations when encountering a sharing constraint; if successful, both shared types would afterwards be seen as synonyms for one and the same type. A very minimal version of this option would suffice for labels; in general, this kind of sharing constraints is non-trivial, but useful (if we could share classes and instances defined multiple times, like the instances for (,,,,,,,,,,,) discussed in other threads). | 3. introduce a least upper bound for shared label imports | (so A and B could just 'import Data.Label(pointX)', which | would magically provide the shared declaration for pointX) with this option, the modules would look like this module A import Data.Label(pointX) module B import Data.Label(pointX) module C import A import B main = print pointX -- no conflict, A.pointX and B.pointX are the same this would have a similarly small effect on the type system as option 1, only that instead of syntax, we'd use imports from the reserved module 'Data.Label' to identify what is a label and what is not. whenever encountering an ' import Data.Label(<identifier>) ', we interpret ' Data.Label.<identifier> ' as a constant of type ' Data.Label.<Identifier> ' and ' <identifier> ' as a constant of type ' <Identifier> '. the difference to normal imports is that the compiler/type system needs to know about 'Data.Label'. In other words, 'Data.Label' does not exist in source or object code, but as a hint for the compiler/type system. Any identifier imported from there is a label of its own type, nothing else can be imported from there. sorry for being so difficult to understand. the questions help. cheers, claus