@@ -25,10 +25,14 @@
26module Data.Generics.Product.Fields
26module Data.Generics.Product.Fields
27 ( -- *Lenses
27 ( -- *Lenses
29 -- $example
29 -- $example
30 HasField (..)
30 HasField (..)
32+ -- *Getter and setter functions
32 -- *Internals
36 -- *Internals
33 , GHasField (..)
37 , GHasField (..)
@@ -58,6 +62,20 @@ import GHC.TypeLits
58-- human = Human \"Tunyasz\" 50 \"London\"
62-- human = Human \"Tunyasz\" 50 \"London\"
67+-- >>> getField @"name" human
69+getField :: forall field a s. HasField field a s => s -> a
70+getField s = s ^. field @field
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)
61-- | Records that have a field with a given name.
79-- | Records that have a field with a given name.
62class HasField (field :: Symbol) a s | s field -> a where
80class HasField (field :: Symbol) a s | s field -> a where
63 -- |A lens that focuses on a field with a given name. Compatible with the
81 -- |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
69 -- Human {name = "Tamas", age = 50, address = "London"}
87 -- Human {name = "Tamas", age = 50, address = "London"}
70 field :: Lens' s a
88 field :: Lens' s a
72−instance (Generic s,
90+instance
73− found ~ FindField field (Rep s),
91+ ( Generic s
74− ErrorUnlessJust field s found,
92+ , ErrorUnlessJust field s (HasFieldP field (Rep s))
76− GHasField field (Rep s) a)
93+ , GHasField field (Rep s) a
78− => HasField field a s where
94+ ) => HasField field a s where
80 field = repIso . gfield @field
96 field = repIso . gfield @field
82−type family ErrorUnlessJust (field :: Symbol) (s :: Type) (found :: Maybe Type) :: Constraint where
98+type family ErrorUnlessJust (field :: Symbol) (s :: Type) (contains :: Bool) :: Constraint where
83− ErrorUnlessJust field s 'Nothing
99+ ErrorUnlessJust field s 'False
84 = TypeError
100 = TypeError
85 ( 'Text "The type "
101 ( 'Text "The type "
86 ':<>: 'ShowType s
102 ':<>: 'ShowType s
@@ -88,7 +104,7 @@ type family ErrorUnlessJust (field :: Symbol) (s :: Type) (found :: Maybe Type)
88 ':<>: 'ShowType field
104 ':<>: 'ShowType field
91− ErrorUnlessJust _ _ ('Just _)
107+ ErrorUnlessJust _ _ 'True
94-- |As 'HasField' but over generic representations as defined by
110-- |As 'HasField' but over generic representations as defined by
@@ -96,10 +112,10 @@ type family ErrorUnlessJust (field :: Symbol) (s :: Type) (found :: Maybe Type)
96class GHasField (field :: Symbol) (f :: Type -> Type) a | field f -> a where
112class GHasField (field :: Symbol) (f :: Type -> Type) a | field f -> a where
97 gfield :: Lens' (f x) a
113 gfield :: Lens' (f x) a
99−instance GProductHasField field l r a (FindField field l)
115+instance GProductHasField field l r a (HasFieldP field l)
100 => GHasField field (l :*: r) a where
116 => GHasField field (l :*: r) a where
102− gfield = gproductField @field @_ @_ @_ @(FindField field l)
118+ gfield = gproductField @field @_ @_ @_ @(HasFieldP field l)
104instance (GHasField field l a, GHasField field r a)
120instance (GHasField field l a, GHasField field r a)
105 => GHasField field (l :+: r) a where
121 => GHasField field (l :+: r) a where
@@ -118,11 +134,11 @@ instance GHasField field f a => GHasField field (M1 D meta f) a where
118instance GHasField field f a => GHasField field (M1 C meta f) a where
134instance GHasField field f a => GHasField field (M1 C meta f) a where
119 gfield = mIso . gfield @field
135 gfield = mIso . gfield @field
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
122 gproductField :: Lens' ((l :*: r) x) a
138 gproductField :: Lens' ((l :*: r) x) a
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
125 gproductField = first . gfield @field
141 gproductField = first . gfield @field
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
128 gproductField = second . gfield @field
144 gproductField = second . gfield @field