Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 153 lines (107 sloc) 4.287 kb
1ca949a Edward Kmett oxford ,
authored
1 Lens: Lenses, Folds, and Traversals
5e9c11b Edward Kmett better title
authored
2 ==================================
c5c8e5f Edward Kmett 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 Edward Kmett ,
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 Edward Kmett metadata
authored
7
68b7e35 Edward Kmett 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 Edward Kmett tutorial link
authored
9
68b7e35 Edward Kmett shuffled docs
authored
10 Documentation is available through [github](https://ekmett.github.com/lens) or [hackage](http://hackage.haskell.org/package/lens).
0c4742e Edward Kmett added the big uml diagram to the readme
authored
11
e409f0e Edward Kmett lots of examples
authored
12 Examples
13 --------
9af3f66 Edward Kmett metadata
authored
14
e409f0e Edward Kmett lots of examples
authored
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
4255093 Edward Kmett moar examples
authored
23 You can make getters out of pure functions with `to`.
e409f0e Edward Kmett lots of examples
authored
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
4255093 Edward Kmett moar examples
authored
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
e409f0e Edward Kmett lots of examples
authored
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
4ad5dda Edward Kmett ]
authored
93 ghci> mapMOf (traverse._2) (\xs -> length xs <$ putStrLn xs) [(42,"hello"),(56,"world")]
e409f0e Edward Kmett lots of examples
authored
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
4255093 Edward Kmett moar examples
authored
108 but you can also flip them around and use them as a lens the other way with `from`
e409f0e Edward Kmett lots of examples
authored
109
110 ```haskell
111 ghci> hello^.from packed.to length
112 5
113 ```
c5c8e5f Edward Kmett repository initialized
authored
114
4255093 Edward Kmett moar examples
authored
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
08d2801 Edward Kmett linking madness
authored
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
68b7e35 Edward Kmett shuffled docs
authored
140 Field Guide
141 -----------
142
143 [![Lens Hierarchy](https://s3.amazonaws.com/creately-published/h5nyo9ne1)](https://creately.com/diagram/h5nyo9ne1/LBbRz63yg4yQsTXGLtub1bQU4%3D)
144
c5c8e5f Edward Kmett repository initialized
authored
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.