GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2024-02-27T15:47:53Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/24483Can't re-export duplicate field names from identical constructor names2024-02-27T15:47:53ZTom EllisCan't re-export duplicate field names from identical constructor namesThis is a new ticket to track [an issue explained by @adamgundry](https://gitlab.haskell.org/ghc/ghc/-/issues/13352#note_294968) in a prior (closed) ticket. That is, the following code leads to the following error. The error is still pr...This is a new ticket to track [an issue explained by @adamgundry](https://gitlab.haskell.org/ghc/ghc/-/issues/13352#note_294968) in a prior (closed) ticket. That is, the following code leads to the following error. The error is still present as of GHC 9.8. It seems like an artificial limitation and it would be great if it could be lifted. This is particularly annoying if we want to create a custom `Prelude`. It makes it impossible to create a custom `Prelude` containing two different fields with the same name, if their constructors also share the same name.
```
{-# LANGUAGE DuplicateRecordFields #-}
module A where
data S = C { foo :: Int }
{-# LANGUAGE DuplicateRecordFields #-}
module B where
data T = C { foo :: Int }
{-# LANGUAGE DuplicateRecordFields #-}
module C (S(foo), T(foo)) where
import A (S(..))
import B (T(..))
```
```
Conflicting exports for ‘foo’:
‘S(foo)’ exports ‘foo’
imported from ‘A’ at C.hs:5:28-32
(and originally defined at A.hs:3:16-18)
‘T(foo)’ exports ‘foo’
imported from ‘B’ at C.hs:6:28-32
(and originally defined at B.hs:5:14-16)
```
----
It's also an interesting puzzle to try to imagine the implementation details that allow both `foo`s to be used within the same module but not re-exported from the same module! I haven't been able to work it out ...
EDIT: Ah, I think I have an explanation: in a given module, duplicate field names are disambiguated by the module they were imported from plus the constructor name.https://gitlab.haskell.org/ghc/ghc/-/issues/24481Support NoFieldSelectors as a datatype and field annotation2024-02-26T09:45:21ZAdam GundrySupport NoFieldSelectors as a datatype and field annotationThe GHC Steering Committee has accepted [proposal 512: NoFieldSelectors as a datatype and field annotation](https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0512-nofieldselectors-per-datatype.md). This makes it possib...The GHC Steering Committee has accepted [proposal 512: NoFieldSelectors as a datatype and field annotation](https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0512-nofieldselectors-per-datatype.md). This makes it possible to annotate individual datatypes or fields as to whether they should use `FieldSelectors` or `NoFieldSelectors`.https://gitlab.haskell.org/ghc/ghc/-/issues/22156HasField should allow unlifted record fields2024-02-08T08:06:00ZRichard Eisenbergrae@richarde.devHasField should allow unlifted record fieldsIf I say
```hs
data Rec = MkRec { field :: Int# }
```
I should be able to write
```
f :: Rec -> Int
f r = I# r.field
```
(with `-XOverloadedRecordDot`). But I get a kind error here. I think it would be somewhat straightforward to cha...If I say
```hs
data Rec = MkRec { field :: Int# }
```
I should be able to write
```
f :: Rec -> Int
f r = I# r.field
```
(with `-XOverloadedRecordDot`). But I get a kind error here. I think it would be somewhat straightforward to change `HasField` to be more general:
```hs
class HasField (label :: k) (record :: TYPE record_rep) (field :: field_rep) | label record -> field field_rep where
getField :: record -> field
```
Surprises always lurk, but my instinct is that this would Just Work.Adam GundryAdam Gundryhttps://gitlab.haskell.org/ghc/ghc/-/issues/18776Improve "No instance for HasField" error messages2024-01-19T15:09:10ZAdam GundryImprove "No instance for HasField" error messagesThe built-in `HasField x r a` constraint is solved automatically whenever `x` is a field label that belongs to the type `r` (except if the field is not in scope, or for a few other corner cases, e.g. the field type is existential, higher...The built-in `HasField x r a` constraint is solved automatically whenever `x` is a field label that belongs to the type `r` (except if the field is not in scope, or for a few other corner cases, e.g. the field type is existential, higher-rank or unboxed). If it is not solved automatically, however, the error message is typically just
```
No instance for (HasField "foo" T ()) arising from ...
```
which is rather uninformative. It would be better to customise the error reporting:
* If the type `r` is not a record type at all, we could mention that fact.
* If the type `r` is a record type, but does not have the named field, we could suggest similarly-named fields (like how the renamer suggests possibilities for not-in-scope identifiers).
* If the field does belong to the type, but is not in scope, we could say that and suggest importing it.
* If the field type is existential, higher-rank or unboxed, we could explain that such fields cannot be used with `HasField`.https://gitlab.haskell.org/ghc/ghc/-/issues/16232Add setField to HasField2023-11-24T09:00:48ZAdam GundryAdd setField to HasFieldThis ticket is to track the implementation of https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0042-record-set-field.rst as modified by https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0583-hasfiel...This ticket is to track the implementation of https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0042-record-set-field.rst as modified by https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0583-hasfield-redesign.rst.
The following applies to the old proposal, not all of which is relevant to the new design.
----
I've made a start on the implementation but have a question on which I'd appreciate some input: how should the dictionary for `HasField` be generated?
To recap, recall that at present, `HasField x r a` is coercible to `r -> a` so the dictionary can be constructed merely by taking the selector function for the field and wrapping it in an appropriate coercion.
With the proposal, `HasField x r a` will instead be represented as `r -> (a -> r, a)` where the first component of the tuple is an update function. The problem is how to define this update function in Core. This function should perform case analysis on the record data type, where each case replaces the value of the field being updated and preserves all the other fields. For example, given a data type `data T = MkT { foo :: Int, bar :: Bool }` we need to generate
```hs
\ r x -> case r of MkT {foo = _, bar = bar} -> MkT { foo = x, bar = bar }
```
The most obvious approach is to generate well-typed Core for the update function directly, but this seems to be rather complex, in particular because of the worker/wrapper distinction, as one ends up reconstructing much of the typechecking/desugaring for record pattern matching and construction. This also seems like a lot of work to do every time a `HasField` constraint is solved.
Would it be reasonable to generate update functions for fields at definition sites, as we do for selector functions? I've implemented this in the past, and it is relatively simple to generate renamed syntax to feed in to the type-checker. However, this would add some overhead for every field, even if `HasField` was not subsequently used, and would require some naming scheme for update functions.
Or are there other options? Is there some way to solve a `HasField` constraint and construct its dictionary by emitting renamed syntax for subsequent type-checking, such that subsequently solving similar constraints will use the same dictionary?
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 8.7 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | NeilMitchell, simonpj |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Add setField to HasField","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"8.10.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.7","keywords":["ORF"],"differentials":[],"test_case":"","architecture":"","cc":["NeilMitchell","simonpj"],"type":"FeatureRequest","description":"This ticket is to track the implementation of https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0042-record-set-field.rst\r\n\r\nI've made a start on the implementation but have a question on which I'd appreciate some input: how should the dictionary for `HasField` be generated?\r\n\r\nTo recap, recall that at present, `HasField x r a` is coercible to `r -> a` so the dictionary can be constructed merely by taking the selector function for the field and wrapping it in an appropriate coercion.\r\n\r\nWith the proposal, `HasField x r a` will instead be represented as `r -> (a -> r, a)` where the first component of the tuple is an update function. The problem is how to define this update function in Core. This function should perform case analysis on the record data type, where each case replaces the value of the field being updated and preserves all the other fields. For example, given a data type `data T = MkT { foo :: Int, bar :: Bool }` we need to generate\r\n{{{#!hs\r\n\\ r x -> case r of MkT {foo = _, bar = bar} -> MkT { foo = x, bar = bar }\r\n}}}\r\n\r\nThe most obvious approach is to generate well-typed Core for the update function directly, but this seems to be rather complex, in particular because of the worker/wrapper distinction, as one ends up reconstructing much of the typechecking/desugaring for record pattern matching and construction. This also seems like a lot of work to do every time a `HasField` constraint is solved.\r\n\r\nWould it be reasonable to generate update functions for fields at definition sites, as we do for selector functions? I've implemented this in the past, and it is relatively simple to generate renamed syntax to feed in to the type-checker. However, this would add some overhead for every field, even if `HasField` was not subsequently used, and would require some naming scheme for update functions.\r\n\r\nOr are there other options? Is there some way to solve a `HasField` constraint and construct its dictionary by emitting renamed syntax for subsequent type-checking, such that subsequently solving similar constraints will use the same dictionary?","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/24174OverloadedRecordDot: "type" can't be used as a field name2023-11-15T04:02:22ZHaisheng, WuOverloadedRecordDot: "type" can't be used as a field name## Summary
* I cannot use "type" as a field name.
* Looks like same problem as #21226 #20723 but looks like it didn't fix the problem for all others reserved keywords in `reservedid`
## Steps to reproduce
Given following code:
```has...## Summary
* I cannot use "type" as a field name.
* Looks like same problem as #21226 #20723 but looks like it didn't fix the problem for all others reserved keywords in `reservedid`
## Steps to reproduce
Given following code:
```haskell
{-# LANGUAGE OverloadedRecordDot, DataKinds #-}
module Main where
import GHC.Records ( HasField(..) )
data Product = Product
{ prodName :: String
, prodType :: String
}
sampleProduct :: Product
sampleProduct = Product "Foo" "Sport"
instance HasField "type" Product String where
getField :: Product -> String
getField = prodType
main :: IO ()
main = putStrLn sampleProduct.type
```
I got compilation error:
```plaintext
[1 of 2] Compiling Main ( main.hs, main.o ) [Source file changed]
main.hs:19:31: error: [GHC-58481] parse error on input ‘type’
|
19 | main = putStrLn sampleProduct.type
```
## Expected behavior
Compile and run successfully.
## Environment
* GHC version used: 9.6.3
Optional:
* Operating System: MacOS-14.4
* System Architecture:https://gitlab.haskell.org/ghc/ghc/-/issues/23963Cannot disambiguate duplicate pattern synonym record fields in exports2023-10-06T13:18:39ZAdam GundryCannot disambiguate duplicate pattern synonym record fields in exportsConsider the following module:
```hs
{-# LANGUAGE GHC2021 #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE PatternSynonyms #-}
module RecPatSyn (B(B, x)) where
data A = MkA {x_ :: Int}
data B = MkB {x_ :: Int}
pattern A :: Int...Consider the following module:
```hs
{-# LANGUAGE GHC2021 #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE PatternSynonyms #-}
module RecPatSyn (B(B, x)) where
data A = MkA {x_ :: Int}
data B = MkB {x_ :: Int}
pattern A :: Int -> A
pattern A{x} <- MkA x
pattern B :: Int -> B
pattern B{x} <- MkB x
```
There is no way to express the fact that in the export list we mean the `x` originating from pattern synonym `B`. Hence this is rejected with an ambiguous occurrence error:
```
RecPatSyn.hs:5:19: error: [GHC-66025]
• Pattern synonyms can only be bundled with matching type constructors
Couldn't match expected type of ‘B’ with actual type of ‘A’
• In the pattern synonym record selector: x
In the export: B(B, x)
|
5 | module RecPatSyn (B(B, x)) where
| ^^^^^^^
RecPatSyn.hs:5:19: error: [GHC-87543]
• Ambiguous occurrence ‘x’.
It could refer to
either the field ‘x’ of pattern synonym ‘A’,
defined at RecPatSyn.hs:12:11,
or the field ‘x’ of pattern synonym ‘B’,
defined at RecPatSyn.hs:15:11.
• In the export: B(B, x)
|
5 | module RecPatSyn (B(B, x)) where
| ^^^^^^^
```
The "Pattern synonyms can only be bundled with matching type constructors" bit of the error seems to be bogus. Presumably the ambiguous identifier is "resolved" to the first option to allow type-checking to continue. But it leads to the awkward situation where the renamer considers it ambiguous which `x` is meant, yet the type-checker apparently "knows" that `x` cannot come from `A`.
It's not obvious to me how we could do better here, but it's an awkward corner of the `PatternSynonyms`/`DuplicateRecordFields` interaction that I wanted to record.
This was originally reported at https://discourse.haskell.org/t/how-to-export-record-pattern-synonym-duplicate-field-names-in-the-same-module/7594.https://gitlab.haskell.org/ghc/ghc/-/issues/19461Remove AmbiguousFieldOcc2023-09-21T07:10:31ZAdam GundryRemove AmbiguousFieldOccUnder [ghc-proposals#366](https://github.com/ghc-proposals/ghc-proposals/pull/366) we are deprecating the special typechecker-assisted name resolution that `DuplicateRecordFields` uses for "ambiguous" selectors and updates. In GHC 9.2, a...Under [ghc-proposals#366](https://github.com/ghc-proposals/ghc-proposals/pull/366) we are deprecating the special typechecker-assisted name resolution that `DuplicateRecordFields` uses for "ambiguous" selectors and updates. In GHC 9.2, a new warning `-Wambiguous-fields` will give users advance warning of this change (#18966, !4770).
Under the proposal, a subsequent GHC release will remove support entirely. This will allow us to remove `AmbiguousFieldOcc` from the codebase and make consequent simplifications. This ticket is to track this cleanup.Adam GundryAdam Gundryhttps://gitlab.haskell.org/ghc/ghc/-/issues/22382Improve Error message when field is missing on actual Haskell record2023-06-23T12:28:19ZMagnus ViernickelImprove Error message when field is missing on actual Haskell record<!--
READ THIS FIRST: If the feature you are proposing changes the language that GHC accepts
or adds any warnings to `-Wall`, it should be written as a [GHC Proposal](https://github.com/ghc-proposals/ghc-proposals/).
Other features, appr...<!--
READ THIS FIRST: If the feature you are proposing changes the language that GHC accepts
or adds any warnings to `-Wall`, it should be written as a [GHC Proposal](https://github.com/ghc-proposals/ghc-proposals/).
Other features, appropriate for a GitLab feature request, include GHC API/plugin
innovations, new low-impact compiler flags, or other similar additions to GHC.
-->
## Motivation
When having `-XOverloadedRecordDots` on and writing the following code
```haskell
data R = MkR
{ ri :: Int
, rs :: String
}
x :: R -> Bool
x r = r.rb
```
I get the following error message
```
• No instance for (GHC.Records.HasField "rb" R Bool)
arising from selecting the field ‘rb’
• In the expression: r.rb
In an equation for ‘x’: x r = r.rb
|
97 | x r = r.rb
| ^^^^
```
which is arguably too confusing if you just want to use this extension for allowing the record dot syntax.
## Proposal
As this is a Haskell record the error message could just have been "The Haskell record `R` does not have the field `rb`" which is in my opinion easier to decipher for users who don't want to use the actual overloading of the record dot. As it's possible to also declare `HasField` instances for some specific field name (`HasField "rb" R Bool`) it would probably be good to nevertheless include a NB that this error results from a missing `HasField` instance.
I would like to implement this my own, if this was accepted, but I'm new so guidance would be appreciated :smile:
Thanks in advance!https://gitlab.haskell.org/ghc/ghc/-/issues/22267OverloadedRecordDot is broken when records have a constraint2023-06-07T10:31:18ZGautier DI FOLCOOverloadedRecordDot is broken when records have a constraint## Summary
Whenever I try to reference a function with a constraint with OverloadedRecordDot syntax, I have an error.
## Steps to reproduce
While this code compiles:
```
{-# LANGUAGE OverloadedRecordDot #-}
module B where
data R = R...## Summary
Whenever I try to reference a function with a constraint with OverloadedRecordDot syntax, I have an error.
## Steps to reproduce
While this code compiles:
```
{-# LANGUAGE OverloadedRecordDot #-}
module B where
data R = R {myFunc :: String -> Int}
myUsage :: R -> Int
myUsage r = r.myFunc "42"
```
Adding a constraint:
```
{-# LANGUAGE OverloadedRecordDot #-}
module B where
import GHC.Stack
data R = R {myFunc :: HasCallStack => String -> Int}
myUsage :: R -> Int
myUsage r = r.myFunc "42"
```
gives me an error:
```
B.hs:9:13: error:
• No instance for (GHC.Records.HasField "myFunc" R (String -> Int))
arising from selecting the field ‘myFunc’
(maybe you haven't applied a function to enough arguments?)
• In the expression: r.myFunc
In the expression: r.myFunc "42"
In an equation for ‘myUsage’: myUsage r = r.myFunc "42"
|
9 | myUsage r = r.myFunc "42"
```
it also fails with a more classic one:
```
{-# LANGUAGE OverloadedRecordDot #-}
module B where
data R = R {myFunc :: forall a. Show a => a -> Int}
myUsage :: R -> Int
myUsage r = r.myFunc "42"
```
which gives
```
B.hs:7:13: error:
• No instance for (GHC.Records.HasField "myFunc" R (String -> Int))
arising from selecting the field ‘myFunc’
(maybe you haven't applied a function to enough arguments?)
• In the expression: r.myFunc
In the expression: r.myFunc "42"
In an equation for ‘myUsage’: myUsage r = r.myFunc "42"
|
7 | myUsage r = r.myFunc "42"
```
## Expected behavior
I expects the type-check works as there's no constraint (while propagating it).
## Environment
* GHC version used: 9.4.2 / 9.2.2
Optional:
* Operating System: NixOS unstable
* System Architecture: x86_64Gautier DI FOLCOGautier DI FOLCOhttps://gitlab.haskell.org/ghc/ghc/-/issues/22746How to disambiguate data family instances with duplicate record fields?2023-06-05T12:06:38ZPhil de JouxHow to disambiguate data family instances with duplicate record fields?## Summary
I have been upgrading from `ghc-8.10.7` to `ghc-9.2.5` and dealing with the `-Wambiguous-fields` warning as it is deprecating:
> This will not be supported by -XDuplicateRecordFields in future releases of GHC.
`-XOverloaded...## Summary
I have been upgrading from `ghc-8.10.7` to `ghc-9.2.5` and dealing with the `-Wambiguous-fields` warning as it is deprecating:
> This will not be supported by -XDuplicateRecordFields in future releases of GHC.
`-XOverloadedRecordDot` is very nice for field access. For record updates I've been qualifying field names to avoid the ambiguity.
I found a data family with multiple instances in the same module, each a record with `-XDuplicateRecordFields`, and could not find a way to import from this module qualified in order to disambiguate a record update.
## Steps to reproduce
See the repo https://github.com/typechecker/data-family-record-dot for these code snippets:
```haskell
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DuplicateRecordFields #-}
module DataFamily where
import Data.Kind
data Choice = A | B
data family Fam :: Choice -> Type
newtype instance Fam A = FamA{ field :: Int }
newtype instance Fam B = FamB{ field :: Bool }
```
```haskell
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE RecordWildCards #-}
module RecordUpdate where
import DataFamily (Choice(..))
import qualified DataFamily as WhoIsB (Fam(FamB), Fam(field))
toggleBool :: WhoIsB.Fam B -> WhoIsB.Fam B
toggleBool b@WhoIsB.FamB{..} =
b{ WhoIsB.field = not field}
```
```
$ cabal repl
Resolving dependencies...
Build profile: -w ghc-9.4.4 -O1
In order, the following will be built (use -v for more details):
- data-family-record-dot-0.1.0.0 (lib) (first run)
Configuring library for data-family-record-dot-0.1.0.0..
Preprocessing library for data-family-record-dot-0.1.0.0..
GHCi, version 9.4.4: https://www.haskell.org/ghc/ :? for help
[1 of 2] Compiling DataFamily ( src/DataFamily.hs, interpreted )
[2 of 2] Compiling RecordUpdate ( src/RecordUpdate.hs, interpreted )
src/RecordUpdate.hs:7:1: warning: [-Wunused-imports]
The qualified import of ‘Fam(field)’
from module ‘DataFamily’ is redundant
|
7 | import qualified DataFamily as WhoIsB (Fam(FamB), Fam(field))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/RecordUpdate.hs:11:8: warning: [-Wambiguous-fields]
The record update b {WhoIsB.field = not
field} with type DataFamily.R:FamB is ambiguous.
This will not be supported by -XDuplicateRecordFields in future releases of GHC.
|
11 | b{ WhoIsB.field = not field}
| ^^^^^^^^^^^^^^^^^^^^^^^^
Ok, two modules loaded.
```
Note that if I followed the advice of the first warning and remove the qualified import of `Fam(field)` then I get an error.
```diff
- import qualified DataFamily as WhoIsB (Fam(FamB), Fam(field))
+ import qualified DataFamily as WhoIsB (Fam(FamB))
```
```
src/RecordUpdate.hs:11:8: error:
Not in scope: ‘WhoIsB.field’
Suggested fix:
Perhaps you want to add ‘field’ to the import list in the import of
‘DataFamily’ (src/RecordUpdate.hs:7:1-49).
|
11 | b{ WhoIsB.field = not field}
|
```
## Expected behavior
I'd expect to be able to use a qualified import to disambiguate. Is there a way? A workaround is to move one of the data family instances to another module, side-stepping the duplicate record field altogether, but that has import consequences for other consumers of the module (now two imports when there was one required to import all instances).
## Environment
ghc-9.4.4 and ghc-9.2.5 are the same here.https://gitlab.haskell.org/ghc/ghc/-/issues/23040`OverloadedRecordDot` and `COLUMN`-pragmas don't play nice together2023-02-28T15:27:27ZSimon Hengelsol@typeful.net`OverloadedRecordDot` and `COLUMN`-pragmas don't play nice together## Summary
`foo.foo` is accepted while `foo{-# COLUMN 23 #-}.foo` results in a parse error.
This is surprising from a users perspective and can break `OverloadedRecordDot` with source-to-source transformations / pre-processors (as it d...## Summary
`foo.foo` is accepted while `foo{-# COLUMN 23 #-}.foo` results in a parse error.
This is surprising from a users perspective and can break `OverloadedRecordDot` with source-to-source transformations / pre-processors (as it does for me).
## Steps to reproduce
```
{-# LANGUAGE NoFieldSelectors #-}
{-# LANGUAGE OverloadedRecordDot #-}
data Foo = Foo { foo :: String }
foo :: Foo
foo = Foo "foo"
main :: IO ()
main = do
putStrLn foo.foo -- works
putStrLn foo{-# COLUMN 23 #-}.foo -- parse error
```
## Expected behavior
Both `foo.foo` and `foo{-# COLUMN 23 #-}.foo` should be accepted.
## Investigation
`foo.foo` is tokenized to:
[ITvarid "foo", ITproj False, ITvarid "bar"]
However, `foo{-# COLUMN 23 #-}.foo` is tokenized to:
[ITvarid "foo", ITproj True, ITvarid "bar"]
So from what I understand, even though this manifests as a parse error, the bug is actually in the lexer.
## Environment
* GHC version used: 9.6.0.20230111
Optional:
* Operating System: Linux
* System Architecture: x86_64https://gitlab.haskell.org/ghc/ghc/-/issues/21324HasField instances cannot be defined on newtypes that have a field selector e...2022-06-12T06:54:36ZOllie CharlesHasField instances cannot be defined on newtypes that have a field selector even if that isn't exported## Motivation
I would like to able to provide a `HasField` instance for `reactive-banana` [`Behavior`](https://hackage.haskell.org/package/reactive-banana-1.3.0.0/docs/Reactive-Banana-Combinators.html#t:Behavior)s. Specifically, I want ...## Motivation
I would like to able to provide a `HasField` instance for `reactive-banana` [`Behavior`](https://hackage.haskell.org/package/reactive-banana-1.3.0.0/docs/Reactive-Banana-Combinators.html#t:Behavior)s. Specifically, I want to write
```haskell
instance HasField x a b => HasField (x :: Symbol) (Behavior a) (Behavior b) where
getField behavior = behavior <&> getField @x
```
Unfortunately, GHC refuses to allow me to write this, reporting:
```
lib/Reactive/Banana/Orphans.hs:36:28: error:
• Illegal instance declaration for
‘HasField x (Behavior a) (Behavior b)’
Behavior has fields
• In the instance declaration for
‘HasField (x :: Symbol) (Behavior a) (Behavior b)’
|
36 | instance HasField x a b => HasField (x :: Symbol) (Behavior a) (Behavior b) where
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
but I disagree that `Behavior` has fields. *Internally* `Behavior` is defined as
```haskell
newtype Behavior a = B { unB :: Prim.Behavior a }
```
but that is never exported - no module expect the defining one can see that field.
## Proposal
I am able to write the instance.https://gitlab.haskell.org/ghc/ghc/-/issues/20113Should we allow a newtype with a representation-polymorphic field with NoFiel...2022-06-11T06:47:37Zsheafsam.derbyshire@gmail.comShould we allow a newtype with a representation-polymorphic field with NoFieldSelectors?The following newtype declaration is accepted:
```haskell
{-# LANGUAGE PolyKinds, UnliftedNewtypes#-}
import GHC.Exts
newtype X (a :: TYPE rep) = MkX a
```
However, the following is rejected:
```haskell
{-# LANGUAGE PolyKinds, Unlift...The following newtype declaration is accepted:
```haskell
{-# LANGUAGE PolyKinds, UnliftedNewtypes#-}
import GHC.Exts
newtype X (a :: TYPE rep) = MkX a
```
However, the following is rejected:
```haskell
{-# LANGUAGE PolyKinds, UnliftedNewtypes, NoFieldSelectors #-}
import GHC.Exts
newtype Y (a :: TYPE rep) = MkY { y_fld :: a }
```
```
A representation-polymorphic type is not allowed here:
Type: a
Kind: TYPE rep
In the type of binder `$sel:y_fld:MkY'
|
4 | newtype Y (a :: TYPE rep) = MkY { y_fld :: a }
| ^^^^^
```
The problem is that the field selector is still generated internally (whence the mangled selector name `$sel:y_fld:MkY` leaking out into the error message), which runs into trouble with the representation polymorphism checks.
I'm not sure exactly what to do. We could continue to reject the program (possibly improving the error message); we could not generate the field selector at all; or we could somehow attempt to generate a representation polymorphic selector which must be representation-monomorphic at use-sites.
cc-ing @adamgundry and @simonpj for thoughts.https://gitlab.haskell.org/ghc/ghc/-/issues/19463Refactor RecordUpd2022-06-11T06:30:58ZShayne Fletchershayne@shaynefletcher.orgRefactor RecordUpdRefactoring of record update syntax is required.
Currently, `RecordUpd` looks like this:
```haskell
| RecordUpd
{ rupd_ext :: XRecordUpd p
, rupd_expr :: LHsExpr p
, rupd_flds :: Either [LHsRecUpdField p] [LHsRecUpd...Refactoring of record update syntax is required.
Currently, `RecordUpd` looks like this:
```haskell
| RecordUpd
{ rupd_ext :: XRecordUpd p
, rupd_expr :: LHsExpr p
, rupd_flds :: Either [LHsRecUpdField p] [LHsRecUpdProj p]
}
```
The `Right` case was added in support of `OverloadedRecordUpdates`.
We intend to refactor `LHsRecUpdField` to something based on `NonEmpty` and use it to eliminate `LHsRecUpdProj` and get `RecordUpd` to read
```haskell
| RecordUpd
{ rupd_ext :: XRecordUpd p
, rupd_expr :: LHsExpr p
, rupd_flds :: [LHsRecUpdField p]
}
```
See discussion in [MR 4532](https://gitlab.haskell.org/ghc/ghc/-/merge_requests/4532#note_333335) for some discussion. Branch `wip/T18599-rec-update-rep-nonempty` contains an implementation of the idea in which
```haskell
type HsRecUpdField p = HsRecField' (NonEmpty (AmbiguousFieldOcc p)) (LHsExpr p)
```Shayne Fletchershayne@shaynefletcher.orgShayne Fletchershayne@shaynefletcher.orghttps://gitlab.haskell.org/ghc/ghc/-/issues/13116Allow Overloaded things in patterns2022-05-30T20:08:10ZFacundo DomínguezAllow Overloaded things in patternsThis ticket is motivated by the use of `OverloadedLabels` of the [choice package](http://hackage.haskell.org/package/choice-0.2.0).
One can use a type `Choice "block"` with values `Do #block` and `Don't #block` by using `OverloadedLabel...This ticket is motivated by the use of `OverloadedLabels` of the [choice package](http://hackage.haskell.org/package/choice-0.2.0).
One can use a type `Choice "block"` with values `Do #block` and `Don't #block` by using `OverloadedLabels`. However, in patterns this syntax is forbidden.
```
case block of
Do #block -> ...
Don't #block -> ...
```
It would be nice if overloaded labels desugared to something sensible in patterns, perhaps
```
case block of
Do ((==) (fromLabel (proxy# :: Proxy# "block")) -> True) -> ...
Don't ((==) (fromLabel (proxy# :: Proxy# "block")) -> True) -> ...
```
`OverloadedLists` and `OverloadedStrings` could benefit from a similar solution.