... | ... | @@ -64,17 +64,28 @@ The new definition of `AvailInfo` is: |
|
|
|
|
|
```wiki
|
|
|
data AvailInfo = Avail Name | AvailTC Name [Name] AvailFields
|
|
|
data AvailFlds name = NonOverloaded [name] | Overloaded [OccName]
|
|
|
data AvailFlds name = NonOverloaded [name] | Overloaded [(OccName, name)]
|
|
|
type AvailFields = AvailFlds Name
|
|
|
```
|
|
|
|
|
|
|
|
|
The `AvailTC` constructor represents a type and its pieces that are in scope. Record fields are now stored in a separate list (the third argument). If the fields are not overloaded, we store the selector names, whereas if they are overloaded, we store only the labels.
|
|
|
The `AvailTC` constructor represents a type and its pieces that are in scope. Record fields are now stored separately in the third argument. If the fields are not overloaded, we store only the selector names, whereas if they are overloaded, we store the labels as well. The `IEThingWith name [name] (AvailFlds name)` constructor of `IE` represents a thing that can be imported or exported, and also has a separate argument for fields.
|
|
|
|
|
|
**AMG** This isn't quite enough, because we need to know the module of the selectors. (Data families mean this need not be the same as the parent's module.) I'm inclined to use `Overloaded [(OccName, name)]` in the interests of simplicity, and because otherwise we have to go to some trouble to avoid `gresFromAvails` outside the monad.
|
|
|
|
|
|
Note that an `OccName` and parent is not enough to uniquely identify a selector, because of data families: if we have
|
|
|
|
|
|
The `IEThingWith name [name] [OccName]` constructor of `IE`, which represents a thing that can be imported or exported, stores only the `OccName`s.
|
|
|
```wiki
|
|
|
module M ( F (..) ) where
|
|
|
data family F a
|
|
|
data instance F Int { foo :: Int }
|
|
|
|
|
|
module N ( F (..) ) where
|
|
|
import M ( F(..) )
|
|
|
data instance F Char { foo :: Char }
|
|
|
```
|
|
|
|
|
|
|
|
|
then `N` exports two different selectors with the `OccName``"foo"`. It might be enough to use `(OccName, Module)` instead of `(OccName, name)`, but I'm inclined to the latter in the interests of simplicity, and because otherwise we have to go to some trouble to avoid `gresFromAvails` outside the monad. In any case, if we want to allow two data family instances in the same module to use the same field name ([see below](records/overloaded-record-fields/implementation#data-families)), the module will not be enough.
|
|
|
|
|
|
### `Parent` and `GlobalRdrElt`
|
|
|
|
... | ... | @@ -238,10 +249,10 @@ instance t ~ Bool => Has (F Bool) "foo" t |
|
|
```
|
|
|
|
|
|
|
|
|
However, what can we call the record selectors? They can't both be `$sel_foo_F`! Ideally we would use the name of the representation tycon, rather than the family tycon, but that isn't introduced until the typechecker (`tcDataFamInstDecl` in `TcInstDcls`), and we need to create the selector in the renamer (`getLocalNonValBinders` in `RnNames`). We can't just pick an arbitrary unique name, because we need to look up the selector to associate it with its data constructor (`extendRecordFieldEnv` in `RnSource`).
|
|
|
However, what can we call the record selectors? They can't both be `$sel_foo_F`! Ideally we would use the name of the representation tycon, rather than the family tycon, but that isn't introduced until the typechecker (`tcDataFamInstDecl` in `TcInstDcls`), and we need to create the selector in the renamer (`getLocalNonValBinders` in `RnNames`). We can't just pick an arbitrary unique name, because we need to look up the selector and dfuns/axioms later.
|
|
|
|
|
|
|
|
|
For the moment, I've simply disallowed duplicate fields for a single data family in a single module. It's fine to duplicate fields between different data families or across different modules, however.
|
|
|
For the moment, I've simply disallowed duplicate fields for a single data family in a single module. There are still problems if a field is duplicated for a single family across different modules. It's fine to duplicate fields between different data families, however.
|
|
|
|
|
|
## Mangling selector names
|
|
|
|
... | ... | @@ -261,6 +272,7 @@ We could mangle selector names (using `$sel_foo_T` instead of `foo`) even when t |
|
|
- When there is only one thing in scope, what should we do?
|
|
|
- Add `HsVarOut RdrName id` instead of `HsSingleRecFld` (or perhaps rename `HsVar` to `HsVarIn`); also useful to recall how the user referred to something.
|
|
|
|
|
|
- What to do about data families with overloaded fields?
|
|
|
- Support virtual fields or forbid them?
|
|
|
- Sort out reporting of unused imports.
|
|
|
- Haddock omits fields from HTML index and prints selector names in LaTeX exports list.
|
... | ... | |