|
|
|
# Tweaks to the existing record system
|
|
|
|
|
|
|
|
|
|
|
|
This page is used to discuss _minor_ tweaks to the existing record system if it is decided that it will be left in basically unchanged. radical or brand new record systems should be discussed elsewhere.
|
|
|
|
|
|
|
|
- reallow punning, Foo {x,y,z} would be interpreted as Foo {x = x, y = y, z = z} in both declaration and pattern matching contexts.
|
|
|
|
## Punning
|
|
|
|
|
|
|
|
|
|
|
|
Reallow punning, Foo {x,y,z} would be interpreted as Foo {x = x, y = y, z = z} in both declaration and pattern matching contexts.
|
|
|
|
|
|
|
|
- update syntax should not bottom out when fields are undefined. as in
|
|
|
|
## Update
|
|
|
|
|
|
|
|
|
|
|
|
Update syntax should not bottom out when fields are undefined. as in
|
|
|
|
|
|
|
|
```wiki
|
|
|
|
|
| ... | ... | @@ -20,17 +28,17 @@ This would make the update syntax actually useful |
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
- label-based pattern matching
|
|
|
|
## Label-based pattern-matching
|
|
|
|
|
|
|
|
> >
|
|
|
|
> > the function:
|
|
|
|
> >
|
|
|
|
> > ```wiki
|
|
|
|
> > f val { x = "foo" } = 4
|
|
|
|
> > ```
|
|
|
|
> >
|
|
|
|
> >
|
|
|
|
> > should match if passed a Foo or a Bar with x being equal to "foo" and val would be bound to its argument (like an @
|
|
|
|
>
|
|
|
|
> the function:
|
|
|
|
>
|
|
|
|
> ```wiki
|
|
|
|
> f val { x = "foo" } = 4
|
|
|
|
> ```
|
|
|
|
>
|
|
|
|
>
|
|
|
|
> should match if passed a Foo or a Bar with x being equal to "foo" and val would be bound to its argument (like an @
|
|
|
|
|
|
|
|
|
|
|
|
pattern)
|
| ... | ... | @@ -51,13 +59,11 @@ pattern) |
|
|
|
> like 'f' has an argument 'val' and another arguement that is a free-standing record,
|
|
|
|
> something we really want in the end anyhow. Not sure how to fix this. val@{x="foo")?
|
|
|
|
|
|
|
|
- first class update and setting syntax (more advanced, needs better syntax)
|
|
|
|
## First-class syntax
|
|
|
|
|
|
|
|
> >
|
|
|
|
> > A syntax for updating and setting fields should be allowed.
|
|
|
|
|
|
|
|
> >
|
|
|
|
> > some possibilites are
|
|
|
|
First class update and setting syntax (more advanced, needs better syntax).
|
|
|
|
A syntax for updating and setting fields should be allowed. Some possibilites are
|
|
|
|
|
|
|
|
```wiki
|
|
|
|
|
| ... | ... | @@ -73,28 +79,28 @@ would be equivalent to |
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
- polymorphic record update
|
|
|
|
|
|
|
|
> >
|
|
|
|
> > Given a record like:
|
|
|
|
> >
|
|
|
|
> > ```wiki
|
|
|
|
> > data Foo a = Foo { bar :: a }
|
|
|
|
> > ```
|
|
|
|
> >
|
|
|
|
> >
|
|
|
|
> > it would be nice to be able to update it like:
|
|
|
|
> >
|
|
|
|
> > ```wiki
|
|
|
|
> > f = Foo { bar = 'a' }
|
|
|
|
> > g = f { bar = False }
|
|
|
|
> > ```
|
|
|
|
> >
|
|
|
|
> >
|
|
|
|
> > Note the change in the type of the stored field. At the moment, such a record update must be written using the
|
|
|
|
> > data constructor, not the update syntax.
|
|
|
|
|
|
|
|
## open statement
|
|
|
|
## Polymorphic record update
|
|
|
|
|
|
|
|
>
|
|
|
|
> Given a record like:
|
|
|
|
>
|
|
|
|
> ```wiki
|
|
|
|
> data Foo a = Foo { bar :: a }
|
|
|
|
> ```
|
|
|
|
>
|
|
|
|
>
|
|
|
|
> it would be nice to be able to update it like:
|
|
|
|
>
|
|
|
|
> ```wiki
|
|
|
|
> f = Foo { bar = 'a' }
|
|
|
|
> g = f { bar = False }
|
|
|
|
> ```
|
|
|
|
>
|
|
|
|
>
|
|
|
|
> Note the change in the type of the stored field. At the moment, such a record update must be written using the
|
|
|
|
> data constructor, not the update syntax.
|
|
|
|
|
|
|
|
## 'Open' statement
|
|
|
|
|
|
|
|
|
|
|
|
having the ability to 'open' a record bringing all its values into scope would be useful for techniques such as first class modules when combined with [PolymorphicComponents](polymorphic-components). a proposal is
|
| ... | ... | @@ -120,7 +126,7 @@ f x = ... where |
|
|
|
|
|
|
|
open x would be allowed at the top level, in a let binding, or in a where binding.
|
|
|
|
|
|
|
|
## abstraction
|
|
|
|
## Abstraction
|
|
|
|
|
|
|
|
|
|
|
|
It is often useful to limit the ability of users to fill in or access parts of a data type arbitrarily to maintain invariants, instituting the following rule would let you enforce that to some degree:
|
| ... | ... | @@ -129,6 +135,24 @@ It is often useful to limit the ability of users to fill in or access parts of a |
|
|
|
|
|
|
|
|
|
|
|
This would insure that by not exporting a field label, it cannot be gotten around by using positional notation.
|
|
|
|
This fix would also require the polymorphic setting ability mentioned above and would partially mitigate the need for [ReadonlyConstructors](readonly-constructors)
|
|
|
|
|
|
|
|
# Meta-Proposal
|
|
|
|
|
|
|
|
|
|
|
|
Due to a lack of experience with alternative record systems, the consensus seems to be that we should stick with the current system, perhaps with a few of the minor tweaks mentioned above. (Which ones is a question still open for discussion.)
|
|
|
|
|
|
|
|
|
|
|
|
However, the main reason for there being little use of alternative
|
|
|
|
candidates, would seem to be that they are not compatible with current Haskell.
|
|
|
|
Thus, it would be useful to have some mechanism for experimental
|
|
|
|
records to be tried out in real Haskell implementations before the
|
|
|
|
next language committee (Haskell-double-prime) starts its work. Then there might be a possibility of one of them being accepted.
|
|
|
|
|
|
|
|
|
|
|
|
this fix would also require the polymorphic setting ability mentioned above and would partially mitigate the need for [ReadonlyConstructors](readonly-constructors) |
|
|
\ No newline at end of file |
|
|
|
A concrete suggestion is that we separate out everything from the Report to do
|
|
|
|
with named-field records into something like a self-contained addendum.
|
|
|
|
Whilst still an official part of the language standard, it might also be
|
|
|
|
marked as a possibility for future removal. This would make it clear
|
|
|
|
what parts of the language could be changed (or re-used without conflict)
|
|
|
|
in an alternative records system. The re-use part is especially important, since taking some of the same syntax to mean something different is pretty-much essential for useability. |