@@ -25,10 +25,14 @@
2525
2626module Data.Generics.Product.Fields
2727 ( -- *Lenses
28− --
28+
2929 -- $example
3030 HasField (..)
3131
32+ -- *Getter and setter functions
33+ , getField
34+ , setField
35+
3236 -- *Internals
3337 , GHasField (..)
3438 ) where
@@ -58,6 +62,20 @@ import GHC.TypeLits
5862-- human = Human \"Tunyasz\" 50 \"London\"
5963-- @
6064
65+-- | Get 'field'
66+--
67+-- >>> getField @"name" human
68+-- "Tunyasz"
69+getField :: forall field a s. HasField field a s => s -> a
70+getField s = s ^. field @field
71+
72+-- | Set 'field'
73+--
74+-- >>> setField @"age" (setField @"name" "Tamas" human) 30
75+-- Human {name = "Tamas", age = 30, address = "London"}
76+setField :: forall field a s. HasField field a s => a -> s -> s
77+setField = set (field @field)
78+
6179-- | Records that have a field with a given name.
6280class HasField (field :: Symbol) a s | s field -> a where
6381 -- |A lens that focuses on a field with a given name. Compatible with the
@@ -69,18 +87,16 @@ class HasField (field :: Symbol) a s | s field -> a where
6987 -- Human {name = "Tamas", age = 50, address = "London"}
7088 field :: Lens' s a
7189
72−instance (Generic s,
73− found ~ FindField field (Rep s),
74− ErrorUnlessJust field s found,
75− found ~ 'Just a,
76− GHasField field (Rep s) a)
77−
78− => HasField field a s where
90+instance
91+ ( Generic s
92+ , ErrorUnlessJust field s (HasFieldP field (Rep s))
93+ , GHasField field (Rep s) a
94+ ) => HasField field a s where
7995
8096 field = repIso . gfield @field
8197
82−type family ErrorUnlessJust (field :: Symbol) (s :: Type) (found :: Maybe Type) :: Constraint where
83− ErrorUnlessJust field s 'Nothing
98+type family ErrorUnlessJust (field :: Symbol) (s :: Type) (contains :: Bool) :: Constraint where
99+ ErrorUnlessJust field s 'False
84100 = TypeError
85101 ( 'Text "The type "
86102 ':<>: 'ShowType s
@@ -88,7 +104,7 @@ type family ErrorUnlessJust (field :: Symbol) (s :: Type) (found :: Maybe Type)
88104 ':<>: 'ShowType field
89105 )
90106
91− ErrorUnlessJust _ _ ('Just _)
107+ ErrorUnlessJust _ _ 'True
92108 = ()
93109
94110-- |As 'HasField' but over generic representations as defined by
@@ -96,10 +112,10 @@ type family ErrorUnlessJust (field :: Symbol) (s :: Type) (found :: Maybe Type)
96112class GHasField (field :: Symbol) (f :: Type -> Type) a | field f -> a where
97113 gfield :: Lens' (f x) a
98114
99−instance GProductHasField field l r a (FindField field l)
115+instance GProductHasField field l r a (HasFieldP field l)
100116 => GHasField field (l :*: r) a where
101117
102− gfield = gproductField @field @_ @_ @_ @(FindField field l)
118+ gfield = gproductField @field @_ @_ @_ @(HasFieldP field l)
103119
104120instance (GHasField field l a, GHasField field r a)
105121 => GHasField field (l :+: r) a where
@@ -118,11 +134,11 @@ instance GHasField field f a => GHasField field (M1 D meta f) a where
118134instance GHasField field f a => GHasField field (M1 C meta f) a where
119135 gfield = mIso . gfield @field
120136
121−class GProductHasField (field :: Symbol) l r a (found :: Maybe Type) | field l r -> a where
137+class GProductHasField (field :: Symbol) l r a (contains :: Bool) | contains field l r -> a where
122138 gproductField :: Lens' ((l :*: r) x) a
123139
124−instance GHasField field l a => GProductHasField field l r a ('Just a) where
140+instance GHasField field l a => GProductHasField field l r a 'True where
125141 gproductField = first . gfield @field
126142
127−instance GHasField field r a => GProductHasField field l r a 'Nothing where
143+instance GHasField field r a => GProductHasField field l r a 'False where
128144 gproductField = second . gfield @field