GHC.Records.HasField doesn't affect Generic representation
Summary
HasField instance doesn't affect generic representation of the type. Generic based code is not working as expected e.g. Aeson skips these virtual fields and generic-lens accessing virtual field causes compilation error.
Steps to reproduce
module Lib where
import Control.Lens
import Data.Aeson
import Data.Generics.Labels ()
import GHC.Generics
import GHC.OverloadedLabels
import GHC.Records
import Prelude
data Foo = Foo { f00 :: Int } deriving (Show, Eq)
data Bar = Bar { b00 :: Int } deriving (Show, Eq)
instance HasField "bar" Foo Bool where
getField _ = True
deriving instance Generic Foo
deriving instance Generic Bar
$ cabal repl
ghci> GHC.Generics.from (Bar 33)
M1 {unM1 = M1 {unM1 = M1 {unM1 = K1 {unK1 = 33}}}}
ghci> GHC.Generics.from (Foo 33)
M1 {unM1 = M1 {unM1 = M1 {unM1 = K1 {unK1 = 33}}}}
ghci> encode (genericToJSON defaultOptions (Foo 333))
"{\"f00\":333}"
ghci> GR.getField @"bar" (Foo 333)
True
ghci> (Foo 333) ^. #f00
333
ghci> (Foo 333) ^. #bar
<interactive>:79:15: error: [GHC-64725]
• The type Foo does not contain a field named 'bar'.
• In the second argument of ‘(^.)’, namely ‘#bar’
In the expression: (Foo 333) ^. #bar
In an equation for ‘it’: it = (Foo 333) ^. #bar
Expected behavior
ghci> GHC.Generics.from (Foo 33)
M1 {unM1 = M1 {unM1 = M1 {unM1 = K1 {unK1 = 33}} :*: M1 {unM1 = K1 {unK1 = True}}}}
ghci> (Foo 333) ^. #bar
True
Sounds like a big change, but HasField instance promises to give a new field.
Multiple instances of HasField should be appended to data constructor in the alphabetical order.
Environment
- GHC version used: 9.8.1
Optional:
- Operating System: Debian 10
- System Architecture: x86-64