... | @@ -136,10 +136,7 @@ Haskell's existing update syntax is desugarred to a call to `set`: |
... | @@ -136,10 +136,7 @@ Haskell's existing update syntax is desugarred to a call to `set`: |
|
```
|
|
```
|
|
|
|
|
|
|
|
|
|
(That is, with a name or expression preceeding the `{ ... }`. A data constructor prefix continues to use
|
|
(That is, with a name or expression preceeding the `{ ... }`. A data constructor prefix continues to use -XDisambiguateRecordFields.)
|
|
|
|
|
|
>
|
|
|
|
> -XDisambiguateRecordFields.)
|
|
|
|
|
|
|
|
|
|
|
|
It is crucial to this proposal that we can implement a polymorphic field update function (`set`). There's a number of tricky requirements considered below.
|
|
It is crucial to this proposal that we can implement a polymorphic field update function (`set`). There's a number of tricky requirements considered below.
|
... | @@ -165,8 +162,7 @@ The prototype for this proposal has explored updating with a type instance pairi |
... | @@ -165,8 +162,7 @@ The prototype for this proposal has explored updating with a type instance pairi |
|
|
|
|
|
```wiki
|
|
```wiki
|
|
instance (t ~ (String, String)) =>
|
|
instance (t ~ (String, String)) =>
|
|
Has Customer_NameAddress
|
|
Has Customer_NameAddress (Proxy_firstName, Proxy_lastName) t where ...
|
|
(Proxy_firstName, Proxy_lastName) t where ...
|
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
|
... | @@ -205,14 +201,14 @@ The type functions are to handle the possibly-changing types: |
... | @@ -205,14 +201,14 @@ The type functions are to handle the possibly-changing types: |
|
For monomorphic (non-changing) fields, `GetResult` returns `t` and `SetResult` returns `r`, so this amounts to the simpler definitions for `Has/get/set` given earlier.
|
|
For monomorphic (non-changing) fields, `GetResult` returns `t` and `SetResult` returns `r`, so this amounts to the simpler definitions for `Has/get/set` given earlier.
|
|
|
|
|
|
|
|
|
|
These are type families, not associated types, because in many cases, the result from `get` depends only on `fld`, and the result from `set` depends only on the record type `r`. In a few cases, the type function must be sensitive to the combination of field type and record type.
|
|
These are type families, not associated types, because in many cases, the result from `get` depends only on `fld` (not `r`), and the result from `set` depends only on the record type `r` (not `t`). In a few cases, the type function must be sensitive to the combination of field type and record type.
|
|
|
|
|
|
|
|
|
|
The extra `Has` constraint on `set`'s result is to 'improve' `t` by gathering constraints from the type of `set`'s resulting record type.
|
|
The extra `Has` constraint on `set`'s result is to 'improve' `t` by gathering constraints from the type of `set`'s resulting record type.
|
|
|
|
|
|
|
|
|
|
Note that the field value's type `t` is the type to-be in the result, not the type as-was in the record being updated.
|
|
Note that the field value's type `t` is the type to-be in the result, not the type as-was in the record being updated.
|
|
So the result from set has that type \`inserted'.
|
|
So the result from set has that type 'inserted'.
|
|
|
|
|
|
|
|
|
|
Example, based on field `unit_Price`:
|
|
Example, based on field `unit_Price`:
|
... | @@ -236,7 +232,7 @@ Example, based on field `unit_Price`: |
... | @@ -236,7 +232,7 @@ Example, based on field `unit_Price`: |
|
(The method definitions are 'uninteresting', compared to the drama to get the types right.)
|
|
(The method definitions are 'uninteresting', compared to the drama to get the types right.)
|
|
|
|
|
|
|
|
|
|
The extra complexity to support changing type could be somewhat reduced using a separate `Set` class with four type parameters, including both as-was and resulting record types, and equality constraints to improve them -- rather than type family `SetResult`.
|
|
The extra complexity to support changing type could be somewhat reduced using a separate `Set` class with four type parameters, including both as-was and resulting record types, and equality constraints to improve them (and to improve the result from `get`) -- rather than type family `SetResult` and `GetResult`.
|
|
|
|
|
|
|
|
|
|
This would mean, though, that the type sugar for `Has` constraints would not be adequate. Since that sugar is to be visible but the instance definitions are to be 'internal', this proposal prefers to support the sugar.
|
|
This would mean, though, that the type sugar for `Has` constraints would not be adequate. Since that sugar is to be visible but the instance definitions are to be 'internal', this proposal prefers to support the sugar.
|
... | @@ -260,10 +256,11 @@ To support higher-ranked fields, this proposal follows SORF's approach (with thr |
... | @@ -260,10 +256,11 @@ To support higher-ranked fields, this proposal follows SORF's approach (with thr |
|
-- field's type is whatever's there (it's opaque)
|
|
-- field's type is whatever's there (it's opaque)
|
|
-- improved by the instance constraint
|
|
-- improved by the instance constraint
|
|
type instance SetResult HR Proxy_rev t = HR
|
|
type instance SetResult HR Proxy_rev t = HR
|
|
-- the H-R type is hidded inside HR
|
|
-- the higer-ranked type is hidded inside HR
|
|
instance (t ~ ([a_] -> [a_])) => -- same as SORF
|
|
instance (t ~ ([a_] -> [a_])) => -- same as SORF
|
|
Has HR Proxy_rev t where
|
|
Has HR Proxy_rev t where
|
|
get HR{rev} _ = rev
|
|
get HR{rev} _ = rev
|
|
|
|
-- set _ fn HR{..} = HR{rev = fn, ..} -- compile fails: can't match fn's type to rev's
|
|
```
|
|
```
|
|
|
|
|
|
### Updating polymorphic/higher-ranked fields
|
|
### Updating polymorphic/higher-ranked fields
|
... | @@ -287,7 +284,7 @@ Is it a requirement to be able to update polymorphic fields? Is it sufficient to |
... | @@ -287,7 +284,7 @@ Is it a requirement to be able to update polymorphic fields? Is it sufficient to |
|
|
|
|
|
See the discussion under \<Application Programmer's view\> and [ http://hackage.haskell.org/trac/ghc/wiki/Records/DeclaredOverloadedRecordFields/NoMonoRecordFields](http://hackage.haskell.org/trac/ghc/wiki/Records/DeclaredOverloadedRecordFields/NoMonoRecordFields). When import/exporting do we need to also export the Proxy_type? If not exported, update syntax cannot be desuggarred to use it.)
|
|
See the discussion under \<Application Programmer's view\> and [ http://hackage.haskell.org/trac/ghc/wiki/Records/DeclaredOverloadedRecordFields/NoMonoRecordFields](http://hackage.haskell.org/trac/ghc/wiki/Records/DeclaredOverloadedRecordFields/NoMonoRecordFields). When import/exporting do we need to also export the Proxy_type? If not exported, update syntax cannot be desuggarred to use it.)
|
|
|
|
|
|
### Should application programmers declare instances for \`Has'/set?
|
|
### Should application programmers declare instances for `Has/set`?
|
|
|
|
|
|
|
|
|
|
Nothing so far suggests they should. (And there's obvious dangers in allowing it.)
|
|
Nothing so far suggests they should. (And there's obvious dangers in allowing it.)
|
... | | ... | |