Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 148 lines (104 sloc) 4.002 kB
c5c8e5f @ekmett repository initialized
authored
1 lens
2 ====
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
b65890a @ekmett tutorial link
authored
8 An overview of the derivation of setters, folds, traversals, getters and lenses can be found on the lens wiki under [Tutorial](https://github.com/ekmett/lens/wiki/Tutorial).
9
f9a94f6 @ekmett better linkage for the diagram
authored
10 [![Lens Hierarchy](https://s3.amazonaws.com/creately-published/h5nyo9ne1)](https://creately.com/diagram/h5nyo9ne1/LBbRz63yg4yQsTXGLtub1bQU4%3D)
0c4742e @ekmett added the big uml diagram to the readme
authored
11
e409f0e @ekmett lots of examples
authored
12 Examples
13 --------
9af3f66 @ekmett metadata
authored
14
e409f0e @ekmett 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 @ekmett moar examples
authored
23 You can make getters out of pure functions with `to`.
e409f0e @ekmett 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 @ekmett 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 @ekmett 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 @ekmett ]
authored
93 ghci> mapMOf (traverse._2) (\xs -> length xs <$ putStrLn xs) [(42,"hello"),(56,"world")]
e409f0e @ekmett 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 @ekmett moar examples
authored
108 but you can also flip them around and use them as a lens the other way with `from`
e409f0e @ekmett lots of examples
authored
109
110 ```haskell
111 ghci> hello^.from packed.to length
112 5
113 ```
c5c8e5f @ekmett repository initialized
authored
114
4255093 @ekmett 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 @ekmett 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
c5c8e5f @ekmett repository initialized
authored
140 Contact Information
141 -------------------
142
143 Contributions and bug reports are welcome!
144
145 Please feel free to contact me through github or on the #haskell IRC channel on irc.freenode.net.
146
147 -Edward Kmett
Something went wrong with that request. Please try again.