Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 158 lines (110 sloc) 4.59 kB
1ca949a @ekmett oxford ,
authored
1 Lens: Lenses, Folds, and Traversals
5e9c11b @ekmett better title
authored
2 ==================================
c5c8e5f @ekmett repository initialized
authored
3
4 [![Build Status](https://secure.travis-ci.org/ekmett/lens.png?branch=master)](http://travis-ci.org/ekmett/lens)
5
2f342e4 @ekmett ,
authored
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).
9af3f66 @ekmett metadata
authored
7
68b7e35 @ekmett shuffled docs
authored
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).
b65890a @ekmett tutorial link
authored
9
68b7e35 @ekmett shuffled docs
authored
10 Documentation is available through [github](https://ekmett.github.com/lens) or [hackage](http://hackage.haskell.org/package/lens).
0c4742e @ekmett added the big uml diagram to the readme
authored
11
a23571c @ekmett Refactored 'at' and 'contains' into 'Control.Lens.IndexedLens'
authored
12 Plated
13 ------
14
15 New in version 2.5 is a port of the `Uniplate` API, updated to use `Traversal`. The Data-derived `biplate` and `uniplate` combinators run about 25% faster than the original `uniplate`, and you can use any of the other combinators, since `biplate` and `uniplate` are now just traversals.
16
e409f0e @ekmett lots of examples
authored
17 Examples
18 --------
9af3f66 @ekmett metadata
authored
19
e409f0e @ekmett lots of examples
authored
20 You can read from lenses (or other getters) and they compose in the order an imperative programmer would expect.
21
22 ```haskell
23 ghci> :m + Control.Lens
24 ghci> ("hello",("world","!!!"))^._2._1
25 "world"
26 ```
27
4255093 @ekmett moar examples
authored
28 You can make getters out of pure functions with `to`.
e409f0e @ekmett lots of examples
authored
29
30
31 ```haskell
32 ghci> ("hello",("world","!!!"))^._2._1.to length
33 5
34 ```
35
36 You can write to lenses and these writes can change the type of the container.
37
38 ```haskell
39 ghci> _1 .~ "hello" $ ((),"world")
40 ("hello","world)
41 ```
42
4255093 @ekmett moar examples
authored
43 You can let the library automatically derive lenses for fields of your data type
44
45 ```haskell
46 import Control.Lens
47
48 data Foo a = Foo { _bar :: Int, _baz :: Int, _quux :: a }
49 makeLenses ''Foo
50 ```
51
52 This will automatically generate the following lenses:
53
54 ```haskell
55 bar, baz :: Simple Lens (Foo a) Int
56 quux :: Lens (Foo a) (Foo b) a b
57 ```
58
e409f0e @ekmett lots of examples
authored
59 You can also write to setters that target multiple parts of a structure, or their composition with other
60 lenses or setters.
61
62 ```haskell
63 ghci> _1.mapped._2.mapped %~ succ $ ([(42, "hello")],"world")
64 ([(42, "ifmmp")],"world")
65 ```
66
67 ```haskell
68 ghci> both *~ 2 $ (1,2)
69 (2,4)
70 ```
71
72 There are combinators for manipulating the current state in a state monad as well
73
74 ```haskell
75 fresh :: MonadState Int m => m Int
76 fresh = id <+= 1
77 ```
78
79 Anything you know how to do with a `Foldable` container, you can do with a `Fold`
80
81 ```haskell
82 ghci> :m + Data.Char Data.Text.Lens
83 ghci> allOf (folded.text) isLower ["hello"^.packed, "goodbye"^.packed]
84 True
85 ```
86
87 You can also use this for generic programming:
88
89 ```haskell
90 ghci> :m + GHC.Generics.Lens
91 ghci> anyOf every (=="world") ("hello",(),[(2::Int,"world")])
92 True
93 ```
94
95 Anything you know how to do with a `Traversable` you can do with a `Traversal`.
96
97 ```haskell
4ad5dda @ekmett ]
authored
98 ghci> mapMOf (traverse._2) (\xs -> length xs <$ putStrLn xs) [(42,"hello"),(56,"world")]
e409f0e @ekmett lots of examples
authored
99 "hello"
100 "world"
101 [(42,5),(56,5)]
102 ```
103
104 Many of the lenses supplied are isomorphisms, that means you can use them directly as a lens:
105
106 ```haskell
107 ghci> let hello = "hello"^.packed
108 "hello"
109 ghci> :t hello
110 hello :: Text
111 ```
112
4255093 @ekmett moar examples
authored
113 but you can also flip them around and use them as a lens the other way with `from`
e409f0e @ekmett lots of examples
authored
114
115 ```haskell
116 ghci> hello^.from packed.to length
117 5
118 ```
c5c8e5f @ekmett repository initialized
authored
119
4255093 @ekmett moar examples
authored
120 You can automatically derive isomorphisms for your own newtypes with `makeIso`. e.g.
121
122 ```haskell
123 newtype Neither a b = Neither { _nor :: Either a b } deriving (Show)
124 makeIso ''Neither
125 ```
126
127 will automatically derive
128
129 ```haskell
130 neither :: Iso (Neither a b) (Neither c d) (Either a b) (Either c d)
131 nor :: Iso (Either a b) (Either c d) (Neither a b) (Neither c d)
132 ```
133
134 such that
135
136 ```haskell
137 from neither = nor
138 from nor = neither
139 neither.nor = id
140 nor.neither = id
141 ```
142
08d2801 @ekmett linking madness
authored
143 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.
144
68b7e35 @ekmett shuffled docs
authored
145 Field Guide
146 -----------
147
148 [![Lens Hierarchy](https://s3.amazonaws.com/creately-published/h5nyo9ne1)](https://creately.com/diagram/h5nyo9ne1/LBbRz63yg4yQsTXGLtub1bQU4%3D)
149
c5c8e5f @ekmett repository initialized
authored
150 Contact Information
151 -------------------
152
153 Contributions and bug reports are welcome!
154
155 Please feel free to contact me through github or on the #haskell IRC channel on irc.freenode.net.
156
157 -Edward Kmett
Something went wrong with that request. Please try again.