Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 149 lines (105 sloc) 3.536 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
7732b26 @ekmett Predicative types
authored
6 This package provides families of lenses, isomorphisms, folds, traversals, getters and setters.
a913fb6 @ekmett reduced snark
authored
7
9af3f66 @ekmett metadata
authored
8 These lenses are compatible with those from lens-family, lens-family-core and lens-family-th,
9 but they provide a great deal of additional flexibility in their composition.
10
b65890a @ekmett tutorial link
authored
11 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).
12
f9a94f6 @ekmett better linkage for the diagram
authored
13 [![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
14
e409f0e @ekmett lots of examples
authored
15 Examples
16 --------
9af3f66 @ekmett metadata
authored
17
e409f0e @ekmett lots of examples
authored
18 You can read from lenses (or other getters) and they compose in the order an imperative programmer would expect.
19
20 ```haskell
21 ghci> :m + Control.Lens
22 ghci> ("hello",("world","!!!"))^._2._1
23 "world"
24 ```
25
4255093 @ekmett moar examples
authored
26 You can make getters out of pure functions with `to`.
e409f0e @ekmett lots of examples
authored
27
28
29 ```haskell
30 ghci> ("hello",("world","!!!"))^._2._1.to length
31 5
32 ```
33
34 You can write to lenses and these writes can change the type of the container.
35
36 ```haskell
37 ghci> _1 .~ "hello" $ ((),"world")
38 ("hello","world)
39 ```
40
4255093 @ekmett moar examples
authored
41 You can let the library automatically derive lenses for fields of your data type
42
43 ```haskell
44 import Control.Lens
45
46 data Foo a = Foo { _bar :: Int, _baz :: Int, _quux :: a }
47 makeLenses ''Foo
48 ```
49
50 This will automatically generate the following lenses:
51
52 ```haskell
53 bar, baz :: Simple Lens (Foo a) Int
54 quux :: Lens (Foo a) (Foo b) a b
55 ```
56
e409f0e @ekmett lots of examples
authored
57 You can also write to setters that target multiple parts of a structure, or their composition with other
58 lenses or setters.
59
60 ```haskell
61 ghci> _1.mapped._2.mapped %~ succ $ ([(42, "hello")],"world")
62 ([(42, "ifmmp")],"world")
63 ```
64
65 ```haskell
66 ghci> both *~ 2 $ (1,2)
67 (2,4)
68 ```
69
70 There are combinators for manipulating the current state in a state monad as well
71
72 ```haskell
73 fresh :: MonadState Int m => m Int
74 fresh = id <+= 1
75 ```
76
77 Anything you know how to do with a `Foldable` container, you can do with a `Fold`
78
79 ```haskell
80 ghci> :m + Data.Char Data.Text.Lens
81 ghci> allOf (folded.text) isLower ["hello"^.packed, "goodbye"^.packed]
82 True
83 ```
84
85 You can also use this for generic programming:
86
87 ```haskell
88 ghci> :m + GHC.Generics.Lens
89 ghci> anyOf every (=="world") ("hello",(),[(2::Int,"world")])
90 True
91 ```
92
93 Anything you know how to do with a `Traversable` you can do with a `Traversal`.
94
95 ```haskell
96 ghci> mapMOf (traverse._2) (\xs -> length xs <$ putStrLn xs) [(42,"hello"),(56,"world")
97 "hello"
98 "world"
99 [(42,5),(56,5)]
100 ```
101
102 Many of the lenses supplied are isomorphisms, that means you can use them directly as a lens:
103
104 ```haskell
105 ghci> let hello = "hello"^.packed
106 "hello"
107 ghci> :t hello
108 hello :: Text
109 ```
110
4255093 @ekmett moar examples
authored
111 but you can also flip them around and use them as a lens the other way with `from`
e409f0e @ekmett lots of examples
authored
112
113 ```haskell
114 ghci> hello^.from packed.to length
115 5
116 ```
c5c8e5f @ekmett repository initialized
authored
117
4255093 @ekmett moar examples
authored
118 You can automatically derive isomorphisms for your own newtypes with `makeIso`. e.g.
119
120 ```haskell
121 newtype Neither a b = Neither { _nor :: Either a b } deriving (Show)
122 makeIso ''Neither
123 ```
124
125 will automatically derive
126
127 ```haskell
128 neither :: Iso (Neither a b) (Neither c d) (Either a b) (Either c d)
129 nor :: Iso (Either a b) (Either c d) (Neither a b) (Neither c d)
130 ```
131
132 such that
133
134 ```haskell
135 from neither = nor
136 from nor = neither
137 neither.nor = id
138 nor.neither = id
139 ```
140
c5c8e5f @ekmett repository initialized
authored
141 Contact Information
142 -------------------
143
144 Contributions and bug reports are welcome!
145
146 Please feel free to contact me through github or on the #haskell IRC channel on irc.freenode.net.
147
148 -Edward Kmett
Something went wrong with that request. Please try again.