@@ -28,7 +28,7 @@
28module Data.Generics.Product.Fields
28module Data.Generics.Product.Fields
29 ( -- *Lenses
29 ( -- *Lenses
31− -- $setup
31+ -- $setup
32 HasField (..)
32 HasField (..)
33 , HasField'
33 , HasField'
@@ -46,6 +46,8 @@ import GHC.Generics
46import GHC.TypeLits (Symbol, ErrorMessage(..), TypeError)
46import GHC.TypeLits (Symbol, ErrorMessage(..), TypeError)
49+-- == /Running example:/
49-- >>> :set -XTypeApplications
51-- >>> :set -XTypeApplications
50-- >>> :set -XDataKinds
52-- >>> :set -XDataKinds
51-- >>> :set -XDeriveGeneric
53-- >>> :set -XDeriveGeneric
@@ -55,12 +57,18 @@ import GHC.TypeLits (Symbol, ErrorMessage(..), TypeError)
55-- >>> :m +Data.Generics.Internal.Lens
57-- >>> :m +Data.Generics.Internal.Lens
56-- >>> :m +Data.Function
58-- >>> :m +Data.Function
58−-- data Human a = Human
60+-- data Human a
59−-- { name :: String
62+-- { name :: String
60−-- , age :: Int
63+-- , age :: Int
61−-- , address :: String
64+-- , address :: String
62−-- , other :: a
70+-- , other :: a
64-- deriving (Generic, Show)
72-- deriving (Generic, Show)
65-- human :: Human Bool
73-- human :: Human Bool
66-- human = Human { name = "Tunyasz", age = 50, address = "London", other = False }
74-- human = Human { name = "Tunyasz", age = 50, address = "London", other = False }
@@ -74,13 +82,31 @@ class HasField (field :: Symbol) s t a b | s field -> a, s field b -> t where
74 -- >>> human ^. field @"age"
82 -- >>> human ^. field @"age"
77− -- If the field's type comes from a type parameter, it can be changed:
85+ -- === /Type changing/
78 -- >>> :t human
87 -- >>> :t human
79 -- human :: Human Bool
88 -- human :: Human Bool
80 -- >>> :t human & field @"other" .~ (42 :: Int)
90 -- >>> :t human & field @"other" .~ (42 :: Int)
81 -- human & field @"other" .~ (42 :: Int) :: Human Int
91 -- human & field @"other" .~ (42 :: Int) :: Human Int
82 -- >>> human & field @"other" .~ 42
93 -- >>> human & field @"other" .~ 42
83 -- Human {name = "Tunyasz", age = 50, address = "London", other = 42}
94 -- Human {name = "Tunyasz", age = 50, address = "London", other = 42}
98+ -- >>> human & field @"weight" .~ 42
100+ -- ... The type Human Bool does not contain a field named 'weight'.
103+ -- >>> human & field @"address" .~ ""
105+ -- ... Not all constructors of the type Human Bool
106+ -- ... contain a field named 'address'.
107+ -- ... The offending constructors are:
108+ -- ... HumanNoAddress
84 field :: Lens s t a b
110 field :: Lens s t a b
86type HasField' field s a = HasField field s s a a
112type HasField' field s a = HasField field s s a a
@@ -99,7 +125,7 @@ setField = set (field @f)
100instance -- see Note [Changing type parameters]
126instance -- see Note [Changing type parameters]
101 ( Generic s
127 ( Generic s
102− , ErrorUnless field s (HasTotalFieldP field (Rep s))
128+ , ErrorUnless field s (CollectField field (Rep s))
103 , Generic t
129 , Generic t
104 , s' ~ Proxied s
130 , s' ~ Proxied s
105 , Generic s'
131 , Generic s'
@@ -118,14 +144,24 @@ instance {-# OVERLAPPING #-} HasField f (Void2 t a) t a b where
118instance {-# OVERLAPPING #-} HasField f (Void1 a) (Void1 b) a b where
144instance {-# OVERLAPPING #-} HasField f (Void1 a) (Void1 b) a b where
119 field = undefined
145 field = undefined
121−type family ErrorUnless (field :: Symbol) (s :: Type) (contains :: Bool) :: Constraint where
147+type family ErrorUnless (field :: Symbol) (s :: Type) (stat :: TypeStat) :: Constraint where
122− ErrorUnless field s 'False
148+ ErrorUnless field s ('TypeStat _ _ '[])
123 = TypeError
149 = TypeError
124 ( 'Text "The type "
150 ( 'Text "The type "
125 ':<>: 'ShowType s
151 ':<>: 'ShowType s
126− ':<>: 'Text " does not contain a field named "
152+ ':<>: 'Text " does not contain a field named '"
153+ ':<>: 'Text field ':<>: 'Text "'."
156+ ErrorUnless field s ('TypeStat (n ': ns) _ _)
158+ ( 'Text "Not all constructors of the type "
127− ':<>: 'ShowType field
159+ ':<>: 'ShowType s
160+ ':$$: 'Text " contain a field named '"
161+ ':<>: 'Text field ':<>: 'Text "'."
162+ ':$$: 'Text "The offending constructors are:"
163+ ':$$: ShowConstuctors (n ': ns)
130− ErrorUnless _ _ 'True
166+ ErrorUnless _ _ ('TypeStat '[] '[] _)