on master help sign in
Squashed commit of the following:

commit 0c91b0494e2389f1233360cf8c07ea2049d42ea4 Author: Will Jones <will@sacharissa.co.uk> Date: Tue Aug 1 18:06:36 2017 +0100 Typeset Generic correctly. commit d3ee51568c8d9dff0b171668d94c4216b2c3d806 Author: Will Jones <will@sacharissa.co.uk> Date: Tue Aug 1 18:04:36 2017 +0100 Add more examples to README.md. commit 62ffdb808fdf6dd81ced2942a3ac5ad4b686624a Author: Will Jones <will@sacharissa.co.uk> Date: Tue Aug 1 17:35:19 2017 +0100 Clean up imports.

commitf7fd41975d4d3f06cc6e42aeacd3ae8f7b49e2d0 authorCsongor Kiss <kiss.csongor.kiss@gmail.com> dateTue 1 Aug 2017, 18:53 (9 years ago) parentb8d6f40
3 files changed+132−25
README.md+130−21 src/Data/Generics/Internal/Families/Has.hs+1−2 src/Data/Generics/Product/Positions.hs+1−2
README.md+130−21
@@ -3,25 +3,29 @@
33[![Build
44Status](https://travis-ci.org/kcsongor/generic-lens.svg?branch=master)](https://travis-ci.org/kcsongor/generic-lens)
55
6−Generically derive lenses for accessing fields of data types.
6+Generically derive lenses and prisms for data types.
77
88Available on [Hackage](https://hackage.haskell.org/package/generic-lens)
99
10−This package uses the GHC 8 Generic representation to derive various operations on data structures with a lens interface, including structural subtype relationship between records and positional indexing into arbitrary product types.
10+This package uses the GHC 8 `Generic` representation to derive various operations
11+on data structures with lens interfaces, including structural subtype
12+relationships between records and positional indexing into arbitrary product
13+types.
1114
12−This is made possible by GHC-8's new Generics API, which provides the meta-data
13−at the type-level (previously only value-level meta-data was available).
15+This is made possible by GHC 8's new Generics API, which provides metadata
16+at the type-level (previously only value-level metadata was available).
1417
15−An example can be found in the `examples` folder.
18+Examples can be found in the `examples` folder. This library makes heavy use of
19+[Visible Type Applications](https://ghc.haskell.org/trac/ghc/wiki/TypeApplication).
1620
17−(The library makes heavy use of [Visible Type Applications](https://ghc.haskell.org/trac/ghc/wiki/TypeApplication))
21+## Lenses
1822
19−## Record fields
23+### Record fields
2024
21−Record fields can be accessed by their label.
25+Record fields can be accessed by their label:
2226
2327```haskell
24−data Person = Person { name :: String, age :: Int } deriving (Show, Generic)
28+data Person = Person { name :: String, age :: Int } deriving (Generic, Show)
2529
2630sally :: Person
2731sally = Person "Sally" 25
@@ -32,30 +36,32 @@ sally = Person "Sally" 25
323625
3337
3438>>> setField @"age" 26 sally
35−Person { name = "Sally", age = 26 }
39+Person {name = "Sally", age = 26}
3640
3741>>> sally ^. field @"name"
3842"Sally"
3943
4044>>> sally & field @"name" .~ "Tamas"
41−Person { name = "Tamas", age = 25 }
45+Person {name = "Tamas", age = 25}
4246
47+>>> sally ^. field @"pet"
48+error:
49+ • The type Person does not contain a field named "pet"
4350```
4451
45−## Positional fields
52+### Positional fields
4653
47−Fields can be accessed by their position in the data structure (index starting at 1).
54+Fields can be accessed by their position in the data structure (index starting at 1):
4855
4956```haskell
50−data Point = Point Int Int Int deriving (Show, Generic)
51−data Polygon = Polygon Point Point Point deriving (Show, Generic)
57+data Point = Point Int Int Int deriving (Generic, Show)
58+data Polygon = Polygon Point Point Point deriving (Generic, Show)
5259
5360polygon :: Polygon
5461polygon = Polygon (Point 1 5 3) (Point 2 4 2) (Point 5 7 (-2))
5562```
5663
5764```haskell
58−
5965>>> getPosition @2 polygon
6066Point 2 4 2
6167
@@ -68,19 +74,51 @@ Polygon (Point 26 5 3) (Point 2 4 2) (Point 5 7 (-2))
6874>>> polygon & position @3 . position @2 %~ (+10)
6975Polygon (Point 1 5 3) (Point 2 4 2) (Point 5 17 (-2))
7076
77+>>> polygon ^. position @10
78+error:
79+ • The type Polygon does not contain a field at position 10
7180```
7281
73−Since tuples are an instance of Generic, positional lenses can be used with them.
82+Since tuples are an instance of `Generic`, they also have positional lenses:
7483
7584```haskell
7685>>> (("hello", True), 5) ^. position @1 . position @2
7786True
7887```
7988
80−## Typed fields
81−- TODO
89+### Typed fields
90+
91+Fields can be accessed by their type in the data structure, assuming that this
92+type is unique:
93+
94+```haskell
95+data Person = Person { name :: String, age :: Int } deriving (Generic, Show)
96+data Point = Point Int Int Int deriving (Generic, Show)
97+
98+sally :: Person
99+sally = Person "Sally" 25
100+
101+point :: Point
102+point = Point 1 2 3
103+```
104+
105+```haskell
106+>>> getTyped @String sally
107+"Sally"
82108
83−## Structural subtyping
109+>>> setTyped @Int sally 26
110+Person {name = "Sally", age = 26}
111+
112+>>> point ^. typed @Int
113+error:
114+ • The type Point contains multiple values of type Int; the choice of value is thus ambiguous
115+
116+>>> point & typed @String .~ "Point"
117+error:
118+ • The type Point does not contain a value of type [Char]
119+```
120+
121+### Structural subtyping
84122
85123A record is a (structural) `subtype' of another, if its fields are a superset of
86124those of the other.
@@ -98,7 +136,7 @@ data Animal = Animal
98136 } deriving (Generic, Show)
99137
100138human :: Human
101−human = Human { name = "Tunyasz", age = 50, address = "London" }
139+human = Human {name = "Tunyasz", age = 50, address = "London"}
102140```
103141
104142```haskell
@@ -126,6 +164,77 @@ growUp (Animal name age) = Animal name (age + 50)
126164Human {name = "Tunyasz", age = 60, address = "London"}
127165```
128166
167+## Prisms
168+
169+### Named constructors
170+
171+Constructor components can be accessed using the constructor's name:
172+
173+```haskell
174+type Name = String
175+type Age = Int
176+
177+data Dog = MkDog { name :: Name, age :: Age } deriving (Generic, Show)
178+data Animal = Dog Dog | Cat (Name, Age) | Duck Age deriving (Generic, Show)
179+
180+shep = Dog (MkDog "Shep" 4)
181+mog = Cat ("Mog", 5)
182+donald = Duck 4
183+```
184+
185+```haskell
186+>>> shep ^? _Ctor @"Dog"
187+Just (MkDog {name = "Shep", age = 4})
188+
189+>>> shep ^? _Ctor @"Cat"
190+Nothing
191+
192+>>> mog ^? _Ctor @"Cat"
193+Just ("Mog",5)
194+
195+>>> _Ctor @"Cat" # ("Garfield", 6) :: Animal
196+Cat ("Garfield",6)
197+
198+>>> donald ^? _Ctor @"Giraffe"
199+error:
200+ • The type Animal does not contain a constructor named "Giraffe"
201+```
202+
203+## Typed constructors
204+
205+Constructor components can be accessed using the component's type, assuming
206+that this type is unique:
207+
208+```haskell
209+type Name = String
210+type Age = Int
211+
212+data Dog = MkDog { name :: Name, age :: Age } deriving (Generic, Show)
213+data Animal = Dog Dog | Cat (Name, Age) | Duck Age deriving (Generic, Show)
214+
215+shep = Dog (MkDog "Shep" 4)
216+mog = Cat ("Mog", 5)
217+donald = Duck 4
218+```
219+
220+```haskell
221+>>> mog ^? _Typed @Dog
222+Nothing
223+
224+>>> shep ^? _Typed @Dog
225+Just (MkDog {name = "Shep", age = 4})
226+
227+>>> donald ^? _Typed @Age
228+Just 4
229+
230+>>> donald ^? _Typed @Float
231+error:
232+ • The type Animal does not contain a constructor whose field is of type Float
233+
234+>>> _Typed @Age # 6 :: Animal
235+Duck 6
236+```
237+
129238## Contributors
130239
131240+ [Toby Shaw](https://github.com/TobyShaw)
src/Data/Generics/Internal/Families/Has.hs+1−2
@@ -11,11 +11,10 @@ module Data.Generics.Internal.Families.Has
1111 , HasCtorP
1212 ) where
1313
14+import Data.Type.Bool (type (||), type (&&))
1415import GHC.Generics
1516import GHC.TypeLits
1617
17−import Data.Type.Bool (type (||), type (&&))
18−
1918type family HasTotalFieldP (field :: Symbol) f :: Bool where
2019 HasTotalFieldP field (S1 ('MetaSel ('Just field) _ _ _) (Rec0 t))
2120 = 'True
src/Data/Generics/Product/Positions.hs+1−2
@@ -37,11 +37,10 @@ module Data.Generics.Product.Positions
3737import Data.Generics.Internal.Lens
3838
3939import Data.Kind
40+import Data.Type.Bool
4041import GHC.Generics
4142import GHC.TypeLits
4243
43−import Data.Type.Bool (type (&&), If, Not)
44−
4544-- $example
4645-- @
4746-- module Example where