Focus on a field name of type a within a type s using its Generic
instance.
:{data User a = User { name :: String , age :: a } | LazyUser { name :: String , age :: a , lazy :: Bool } deriving (Show, Generic):}
let user = User "Tom" 32 :: User Intuser ^. gfield @"name""Tom"
user ^. gfield @"age"32
user ^. gfield @"salary"......Data constructor ‘User’ doesn't have a field named ‘salary’...In the......
Only total fields are accessible (for partial ones see gafield):
user ^. gfield @"lazy"......Data constructor ‘User’ doesn't have a field named ‘lazy’...In the......
Type changing updates are supported:
user & gfield @"age" .~ ()User {name = "Tom", age = ()}
Types without a Generic instance are not supported:
NoG 'x' ^. gfield @"any"......Type ‘NoG’ doesn't have a Generic instance...In the......
Note: gfield is supported by labelOptic and can be used
with a concise syntax via OverloadedLabels.
user ^. #name"Tom"
user & #age %~ (+1)User {name = "Tom", age = 33}