1Lens: Lenses, Folds, and Traversals 2================================== 3 4[![Hackage](https://img.shields.io/hackage/v/lens.svg)](https://hackage.haskell.org/package/lens) [![Build Status](https://secure.travis-ci.org/ekmett/lens.svg)](http://travis-ci.org/ekmett/lens) [![Hackage Deps](https://img.shields.io/hackage-deps/v/lens.svg)](http://packdeps.haskellers.com/reverse/lens) 5 6This 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). 7 8If you are looking for where to get started, [a crash course video](http://youtu.be/cefnmjtAolY?hd=1) on how `lens` was constructed and how to use the basics is available on youtube. It is best watched in high definition to see the slides, but the [slides](http://comonad.com/haskell/Lenses-Folds-and-Traversals-NYC.pdf) are also available if you want to use them to follow along. 9 10The [FAQ](https://github.com/ekmett/lens/wiki/FAQ), which provides links to a large number of different resources for learning about lenses and 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 [overview](https://github.com/ekmett/lens/wiki/Overview) and some [examples](https://github.com/ekmett/lens/wiki/Examples). 11 12Documentation is available through [github](http://ekmett.github.com/lens/frames.html) (for HEAD) or [hackage](http://hackage.haskell.org/package/lens) for the current and preceding releases. 13 14Field Guide 15----------- 16 17[![Lens Hierarchy](https://raw.githubusercontent.com/wiki/ekmett/lens/images/Hierarchy.png)](https://creately.com/diagram/h5nyo9ne1/QZ9UBOtw4AJWtmAKYK3wT8Mm1HM%3D) 18 19 20Examples 21-------- 22 23(See [`wiki/Examples`](https://github.com/ekmett/lens/wiki/Examples)) 24 25First, import `Control.Lens`. 26 27```haskell 28ghci> import Control.Lens 29``` 30 31Now, you can read from lenses 32 33```haskell 34ghci> ("hello","world")^._2 35"world" 36``` 37 38and you can write to lenses. 39 40```haskell 41ghci> set _2 42 ("hello","world") 42("hello",42) 43``` 44 45Composing lenses for reading (or writing) goes in the order an imperative programmer would expect, and just uses `(.)` from the `Prelude`. 46 47```haskell 48ghci> ("hello",("world","!!!"))^._2._1 49"world" 50``` 51 52```haskell 53ghci> set (_2._1) 42 ("hello",("world","!!!")) 54("hello",(42,"!!!")) 55``` 56 57You can make a `Getter` out of a pure function with `to`. 58 59```haskell 60ghci> "hello"^.to length 615 62``` 63 64You can easily compose a `Getter` with a `Lens` just using `(.)`. No explicit coercion is necessary. 65 66```haskell 67ghci> ("hello",("world","!!!"))^._2._2.to length 683 69``` 70 71As we saw above, you can write to lenses and these writes can change the type of the container. `(.~)` is an infix alias for `set`. 72 73```haskell 74ghci> _1 .~ "hello" $ ((),"world") 75("hello","world") 76``` 77 78Conversely `view`, can be used as a prefix alias for `(^.)`. 79 80```haskell 81ghci> view _2 (10,20) 8220 83``` 84 85There are a large number of other lens variants provided by the library, in particular a `Traversal` generalizes `traverse` from `Data.Traversable`. 86 87We'll come back to those later, but continuing with just lenses: 88 89You can let the library automatically derive lenses for fields of your data type 90 91```haskell 92data Foo a = Foo { _bar :: Int, _baz :: Int, _quux :: a } 93makeLenses ''Foo 94``` 95 96This will automatically generate the following lenses: 97 98```haskell 99bar, baz :: Lens' (Foo a) Int 100quux :: Lens (Foo a) (Foo b) a b 101``` 102 103A `Lens` takes 4 parameters because it can change the types of the whole when you change the type of the part. 104 105Often you won't need this flexibility, a `Lens'` takes 2 parameters, and can be used directly as a `Lens`. 106 107You can also write to setters that target multiple parts of a structure, or their composition with other 108lenses or setters. The canonical example of a setter is 'mapped': 109 110```haskell 111mapped :: Functor f => Setter (f a) (f b) a b 112``` 113 114`over` is then analogous to `fmap`, but parameterized on the Setter. 115 116```haskell 117ghci> fmap succ [1,2,3] 118[2,3,4] 119ghci> over mapped succ [1,2,3] 120[2,3,4] 121``` 122 123The benefit is that you can use any `Lens` as a `Setter`, and the composition of setters with other setters or lenses using `(.)` yields 124a `Setter`. 125 126```haskell 127ghci> over (mapped._2) succ [(1,2),(3,4)] 128[(1,3),(3,5)] 129``` 130 131`(%~)` is an infix alias for 'over', and the precedence lets you avoid swimming in parentheses: 132 133```haskell 134ghci> _1.mapped._2.mapped %~ succ $ ([(42, "hello")],"world") 135([(42, "ifmmp")],"world") 136``` 137 138There are a number of combinators that resemble the `+=`, `*=`, etc. operators from C/C++ for working with the monad transformers. 139 140There are `+~`, `*~`, etc. analogues to those combinators that work functionally, returning the modified version of the structure. 141 142```haskell 143ghci> both *~ 2 $ (1,2) 144(2,4) 145``` 146 147There are combinators for manipulating the current state in a state monad as well 148 149```haskell 150fresh :: MonadState Int m => m Int 151fresh = id <+= 1 152``` 153 154Anything you know how to do with a `Foldable` container, you can do with a `Fold` 155 156```haskell 157ghci> :m + Data.Char Data.Text.Lens 158ghci> allOf (folded.text) isLower ["hello"^.packed, "goodbye"^.packed] 159True 160``` 161 162You can also use this for generic programming. Combinators are included that are based on Neil Mitchell's `uniplate`, but which 163have been generalized to work on or as lenses, folds, and traversals. 164 165```haskell 166ghci> :m + Data.Data.Lens 167ghci> anyOf biplate (=="world") ("hello",(),[(2::Int,"world")]) 168True 169``` 170 171As alluded to above, anything you know how to do with a `Traversable` you can do with a `Traversal`. 172 173```haskell 174ghci> mapMOf (traverse._2) (\xs -> length xs <$ putStrLn xs) [(42,"hello"),(56,"world")] 175"hello" 176"world" 177[(42,5),(56,5)] 178``` 179 180Moreover, many of the lenses supplied are actually isomorphisms, that means you can use them directly as a lens or getter: 181 182```haskell 183ghci> let hello = "hello"^.packed 184"hello" 185ghci> :t hello 186hello :: Text 187``` 188 189but you can also flip them around and use them as a lens the other way with `from`! 190 191```haskell 192ghci> hello^.from packed.to length 1935 194``` 195 196You can automatically derive isomorphisms for your own newtypes with `makePrisms`. e.g. 197 198```haskell 199newtype Neither a b = Neither { _nor :: Either a b } deriving (Show) 200makePrisms ''Neither 201``` 202 203will automatically derive 204 205```haskell 206neither :: Iso (Neither a b) (Neither c d) (Either a b) (Either c d) 207nor :: Iso (Either a b) (Either c d) (Neither a b) (Neither c d) 208``` 209 210such that 211 212```haskell 213from neither = nor 214from nor = neither 215neither.nor = id 216nor.neither = id 217``` 218 219There 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. 220 221There are also a couple of hundred examples distributed throughout the haddock documentation. 222 223Contact Information 224------------------- 225 226Contributions and bug reports are welcome! 227 228Please feel free to contact me through github or on the #haskell IRC channel on irc.freenode.net. 229 230-Edward Kmett 231