Skip to content
This repository
Newer
Older
100644 152 lines (107 sloc) 4.287 kb
1ca949a2 »
2012-08-09 oxford ,
1 Lens: Lenses, Folds, and Traversals
5e9c11bc »
2012-08-09 better title
2 ==================================
c5c8e5ff »
2012-07-25 repository initialized
3
4 [![Build Status](https://secure.travis-ci.org/ekmett/lens.png?branch=master)](http://travis-ci.org/ekmett/lens)
5
2f342e40 »
2012-08-09 ,
6 This package provides families of [lenses](https://github.com/ekmett/lens/blob/master/src/Control/Lens/Type.hs), [isomorphisms](https://github.com/ekmett/lens/blob/master/src/Control/Lens/Iso.hs), [folds](https://github.com/ekmett/lens/blob/master/src/Control/Lens/Fold.hs), [traversals](https://github.com/ekmett/lens/blob/master/src/Control/Lens/Traversal.hs), [getters](https://github.com/ekmett/lens/blob/master/src/Control/Lens/Getter.hs) and [setters](https://github.com/ekmett/lens/blob/master/src/Control/Lens/Setter.hs).
9af3f66e »
2012-07-31 metadata
7
68b7e354 »
2012-08-09 shuffled docs
8 An overview of the [derivation](https://github.com/ekmett/lens/wiki/Derivation) of these types can be found on the [Lens Wiki](https://github.com/ekmett/lens/wiki) along with a brief [Tutorial](https://github.com/ekmett/lens/wiki/Tutorial).
b65890a3 »
2012-08-08 tutorial link
9
68b7e354 »
2012-08-09 shuffled docs
10 Documentation is available through [github](https://ekmett.github.com/lens) or [hackage](http://hackage.haskell.org/package/lens).
0c4742e6 »
2012-08-09 added the big uml diagram to the readme
11
e409f0e8 »
2012-08-09 lots of examples
12 Examples
13 --------
9af3f66e »
2012-07-31 metadata
14
e409f0e8 »
2012-08-09 lots of examples
15 You can read from lenses (or other getters) and they compose in the order an imperative programmer would expect.
16
17 ```haskell
18 ghci> :m + Control.Lens
19 ghci> ("hello",("world","!!!"))^._2._1
20 "world"
21 ```
22
42550937 »
2012-08-09 moar examples
23 You can make getters out of pure functions with `to`.
e409f0e8 »
2012-08-09 lots of examples
24
25
26 ```haskell
27 ghci> ("hello",("world","!!!"))^._2._1.to length
28 5
29 ```
30
31 You can write to lenses and these writes can change the type of the container.
32
33 ```haskell
34 ghci> _1 .~ "hello" $ ((),"world")
35 ("hello","world)
36 ```
37
42550937 »
2012-08-09 moar examples
38 You can let the library automatically derive lenses for fields of your data type
39
40 ```haskell
41 import Control.Lens
42
43 data Foo a = Foo { _bar :: Int, _baz :: Int, _quux :: a }
44 makeLenses ''Foo
45 ```
46
47 This will automatically generate the following lenses:
48
49 ```haskell
50 bar, baz :: Simple Lens (Foo a) Int
51 quux :: Lens (Foo a) (Foo b) a b
52 ```
53
e409f0e8 »
2012-08-09 lots of examples
54 You can also write to setters that target multiple parts of a structure, or their composition with other
55 lenses or setters.
56
57 ```haskell
58 ghci> _1.mapped._2.mapped %~ succ $ ([(42, "hello")],"world")
59 ([(42, "ifmmp")],"world")
60 ```
61
62 ```haskell
63 ghci> both *~ 2 $ (1,2)
64 (2,4)
65 ```
66
67 There are combinators for manipulating the current state in a state monad as well
68
69 ```haskell
70 fresh :: MonadState Int m => m Int
71 fresh = id <+= 1
72 ```
73
74 Anything you know how to do with a `Foldable` container, you can do with a `Fold`
75
76 ```haskell
77 ghci> :m + Data.Char Data.Text.Lens
78 ghci> allOf (folded.text) isLower ["hello"^.packed, "goodbye"^.packed]
79 True
80 ```
81
82 You can also use this for generic programming:
83
84 ```haskell
85 ghci> :m + GHC.Generics.Lens
86 ghci> anyOf every (=="world") ("hello",(),[(2::Int,"world")])
87 True
88 ```
89
90 Anything you know how to do with a `Traversable` you can do with a `Traversal`.
91
92 ```haskell
4ad5dda5 »
2012-08-09 ]
93 ghci> mapMOf (traverse._2) (\xs -> length xs <$ putStrLn xs) [(42,"hello"),(56,"world")]
e409f0e8 »
2012-08-09 lots of examples
94 "hello"
95 "world"
96 [(42,5),(56,5)]
97 ```
98
99 Many of the lenses supplied are isomorphisms, that means you can use them directly as a lens:
100
101 ```haskell
102 ghci> let hello = "hello"^.packed
103 "hello"
104 ghci> :t hello
105 hello :: Text
106 ```
107
42550937 »
2012-08-09 moar examples
108 but you can also flip them around and use them as a lens the other way with `from`
e409f0e8 »
2012-08-09 lots of examples
109
110 ```haskell
111 ghci> hello^.from packed.to length
112 5
113 ```
c5c8e5ff »
2012-07-25 repository initialized
114
42550937 »
2012-08-09 moar examples
115 You can automatically derive isomorphisms for your own newtypes with `makeIso`. e.g.
116
117 ```haskell
118 newtype Neither a b = Neither { _nor :: Either a b } deriving (Show)
119 makeIso ''Neither
120 ```
121
122 will automatically derive
123
124 ```haskell
125 neither :: Iso (Neither a b) (Neither c d) (Either a b) (Either c d)
126 nor :: Iso (Either a b) (Either c d) (Neither a b) (Neither c d)
127 ```
128
129 such that
130
131 ```haskell
132 from neither = nor
133 from nor = neither
134 neither.nor = id
135 nor.neither = id
136 ```
137
08d28010 »
2012-08-09 linking madness
138 There is also a fully operational, but simple game of [Pong](https://github.com/ekmett/lens/blob/master/examples/Pong.hs) in the [examples/](https://github.com/ekmett/lens/blob/master/examples/) folder.
139
68b7e354 »
2012-08-09 shuffled docs
140 Field Guide
141 -----------
142
143 [![Lens Hierarchy](https://s3.amazonaws.com/creately-published/h5nyo9ne1)](https://creately.com/diagram/h5nyo9ne1/LBbRz63yg4yQsTXGLtub1bQU4%3D)
144
c5c8e5ff »
2012-07-25 repository initialized
145 Contact Information
146 -------------------
147
148 Contributions and bug reports are welcome!
149
150 Please feel free to contact me through github or on the #haskell IRC channel on irc.freenode.net.
151
152 -Edward Kmett
Something went wrong with that request. Please try again.