Tag exported entities with their namespace
In export and import lists, it is easy to distinguish functions from types/constructors/classes, because they are lexically different - vars begin with lower-case, the rest with upper-case. However, it is much more difficult to distinguish types, from constructors, from classes.
Proposal
Each type or class constructor in an import or export list can be (optionally) annotated with its namespace, e.g.
import Foo (class Foo (Foo,Bar), data Baz())
Grammar changes
The production for exported entities changes from
export -> qvar
| qtycon [ (..) | ( cname_1, ... , cname_n ) ] (n>=0)
| qtycls [ (..) | ( var_1, ... , var_n ) ] (n>=0)
| module modid
to
export -> qvar
| [type] qtycon
| [newtype] qtycon [ (..) | ( cname_1, ... , cname_n ) (n>=0)
| [data] qtycon [ (..) | ( cname_1, ... , cname_n ) (n>=0)
| [class] qtycls [ (..) | ( var_1, ... , var_n ) (n>=0)
| module modid
and that for imported entities from
import -> var
| tycon [ (..) | ( cname_1, ... , cname_n ) ] (n>=0)
| tycls [ (..) | ( var_1, ... , var_n ) ] (n>=0)
to
import -> var
| [type] tycon
| [newtype] tycon [ (..) | ( cname_1, ... , cname_n ) ] (n>=0)
| [data] tycon [ (..) | ( cname_1, ... , cname_n ) ] (n>=0)
| [class] tycls [ (..) | ( var_1, ... , var_n ) ] (n>=0)
Variation I
It would be better not to need to distinguish between type, newtype, and data. These names all live in the same namespace. And for implementation-abstract reasons, it would be useful not to need to reveal exactly how a type constructor was defined. So an alternative proposal is to use no keyword for type constructors, but the 'class' keyword for classes. This distinguishes the two capitalised namespaces exactly, and minimally. With this scheme, we should probably remove the optionality of the class keyword.
export -> qvar
| qtycon [ (..) | ( cname_1, ... , cname_n ) (n>=0)
| class qtycls [ (..) | ( var_1, ... , var_n ) (n>=0)
| module modid
import -> var
| tycon [ (..) | ( cname_1, ... , cname_n ) ] (n>=0)
| class tycls [ (..) | ( var_1, ... , var_n ) ] (n>=0)
Variation II
Currently, constructors can not be exported without wrapping them in brackets prefixed by their data type name. If we introduce tags, it would be nice to change that. So an alternative proposal would be the following:
- Any name without a tag is a value-level entity (i.e., a function name or data constructor, depending on case).
- Any type constructor needs to be tagged with type (not distinguishing between data types, newtypes, and synonyms) or with type, newtype, or data (if we want this fine-grained distinction).
- Class names need to be tagged with class.
- Module names need to be tagged with module.
