# lens: Lenses, Folds and Traversals

The combinators in `Control.Lens`

provide a highly generic toolbox for composing
families of getters, folds, traversals, setters and lenses.

*Getter*

A

is just any function `Getter`

a c`(a -> c)`

, which we've flipped into continuation
passing style, `(c -> r) -> a -> r`

and decorated with `Const`

to obtain

type Getting r a b c d = (c -> Const r d) -> a -> Const r b

If we restrict access to knowledge about the type `r`

and can work for any d and b, we get:

type Getter a c = forall r b d. Getting r a b c d

Everything you can do with a function, you can do with a `Getter`

, but note that because of the
continuation passing style (.) composes them in the opposite order.

Since it is only a function, every `Getter`

obviously only retrieves a single value for a given
input.

*Fold*

A

is a generalization of something `Fold`

a c`Foldable`

. It allows you to
extract multiple results from a container. A `Foldable`

container can be
characterized by the behavior of `foldMap :: (Foldable t, Monoid m) => (c -> m) -> t c -> m`

.
Since we want to be able to work with monomorphic containers, we generalize this signature to
`forall m. `

, and then decorate it with `Monoid`

m => (c -> m) -> a -> m`Const`

to obtain

type Fold a c = forall m b d. Monoid m => Getting m a b c d

Every `Getter`

is a valid `Fold`

that simply doesn't use the `Monoid`

it is passed.

Everything you can do with a `Foldable`

container, you can with with a `Fold`

and there are
combinators that generalize the usual `Foldable`

operations in `Control.Lens`

.

*Traversal*

A

is a generalization of `Traversal`

a b c d`traverse`

from `Traversable`

. It allows
you to traverse over a structure and change out its contents with monadic or
applicative side-effects. Starting from

,
we monomorphize the contents and result to obtain`traverse`

:: (`Traversable`

t, `Applicative`

f) => (c -> f d) -> t c -> f (t d)

type Traversal a b c d = forall f. Applicative f => (c -> f d) -> a -> f b

While a `Traversal`

isn't quite a `Fold`

, it _can_ be used for `Getting`

like a `Fold`

, because
given a `Monoid`

`m`

, we have an `Applicative`

for `(`

.`Const`

m)

Everything you can do with a `Traversable`

container, you can with with a `Traversal`

, and there
are combinators that generalize the usual `Traversable`

operations in `Control.Lens`

.

*Setter*

A

is a generalization of `Setter`

a b c d`fmap`

from `Functor`

. It allows you to map into a
structure and change out the contents, but it isn't strong enough to allow you to
enumerate those contents. Starting with `fmap :: `

we monomorphize the type to obtain `Functor`

f => (c -> d) -> f c -> f d`(c -> d) -> a -> b`

and then decorate it with `Identity`

to obtain

type Setter a b c d = (c -> Identity d) -> a -> Identity b

Every `Traversal`

is a valid `Setter`

, since `Identity`

is `Applicative`

.

Everything you can do with a `Functor`

, you can do with a `Setter`

, and there are combinators that
generalize the usual `Functor`

operations in `Control.Lens`

.

*Lens*

A

is a purely functional reference.`Lens`

a b c d

While a `Traversal`

could be used for `Getting`

like a valid `Fold`

, it wasn't a valid `Getter`

.
To make the `Applicative`

for `Const`

it required a `Monoid`

for the argument we passed it, which
a `Getter`

doesn't recieve.

However, the instance of `Functor`

for `Const`

requires no such thing. If we weaken the type
requirement from `Applicative`

to `Functor`

for `Traversal`

, we obtain

type Lens a b c d = forall f. Functor f => (c -> f d) -> a -> f b

Every `Lens`

is a valid `Setter`

, choosing `f`

= `Identity`

.

Every `Lens`

can be used for `Getting`

like a `Fold`

that doesn't use the `Monoid`

it is passed.

Every `Lens`

is a valid `Traversal`

that only uses the `Functor`

part of the `Applicative`

it is supplied.

Every `Lens`

can be used for `Getting`

like a valid `Getter`

, choosing `f`

= `Const`

`r`

for an appropriate `r`

Since every `Lens`

can be used for `Getting`

like a valid `Getter`

it follows that it must view exactly one
element in the structure.

The lens laws follow from this property and the desire for it to act like a `Functor`

when used as a `Setter`

.

*Isomorphisms and Iso*

Control.Isomorphic provides easy overloading of function application for isomorphisms and `Iso a b c d`

uses it
to form isomorphism families that can be composed with other isomorphisms and with lenses, setters, folds,
traversals and getters.

type Iso a b c d = forall k f. (Isomorphic k, Functor f) => k (c -> f d) (a -> f b)

*Composition*

Note that all of these types are type aliases, and you can compose these lenses with mere function compositon.

This is a generalization of the well-known trick for `(.).(.)`

or `fmap.fmap`

, and their less well-known cousins
`foldMap.foldMap`

`traverse.traverse`

. It follows because each one is a function between values of type `(x -> f y)`

and the composition takes the intersection of supplied functionality for you automatically!

*Lens Families*

For a longer description of why you should care about lenses, and an overview of why we use 4 parameters a, b, c, and d instead of just 2, see http://comonad.com/reader/2012/mirrored-lenses/.

Sometimes you won't need the flexibility those extra parameters afford you and you can use

type Simple f a b = f a a b b

to describe a `Simple`

`Setter`

, `Simple`

`Traversal`

, `Simple`

`Lens`

or `Simple`

`Iso`

.

*Avoiding Dependencies*

Note: If you merely want your library to *provide* lenses you may not
have to actually import *any* lens library at all. For, say, a

, just export a function with the signature:`Simple`

`Lens`

Bar Foo

foo :: Functor f => (Foo -> f Foo) -> Bar -> f Bar

and then you can compose it with other lenses using nothing more than `(.)`

from the Prelude.

*Deriving Lenses*

You can derive lenses automatically for many data types using `Control.Lens.TH`

, and if a
container is fully characterized by its lenses, you can use `Control.Lens.Representable`

to
automatically derive `Functor`

, `Applicative`

, `Monad`

, and `Derivable`

.

## Modules

[Index]

*Control**Data**Array**Bits**ByteString**Complex**Dynamic**Either**IntMap**IntSet**List**Map**Pair**Sequence**Set**Text**Tree*

*GHC**Generics*

*Language**Haskell*

## Downloads

- lens-1.4.1.tar.gz [browse] (Cabal source package)
- Package description (as included in the package)

#### Maintainer's Corner

For package maintainers and hackage trustees

Candidates

- No Candidates

Versions [RSS] | 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.0.1, 1.0.2, 1.0.3, 1.1, 1.1.1, 1.2, 1.3, 1.3.1, 1.4, 1.4.1, 1.5, 1.6, 1.7, 1.7.1, 1.8, 1.9, 1.9.1, 2.0, 2.1, 2.2, 2.3, 2.4, 2.4.0.2, 2.5, 2.6, 2.6.1, 2.7, 2.7.0.1, 2.8, 2.9, 3.0, 3.0.1, 3.0.2, 3.0.3, 3.0.4, 3.0.5, 3.0.6, 3.1, 3.2, 3.3, 3.4, 3.5, 3.5.1, 3.6, 3.6.0.1, 3.6.0.2, 3.6.0.3, 3.6.0.4, 3.7, 3.7.0.1, 3.7.0.2, 3.7.1, 3.7.1.1, 3.7.1.2, 3.7.2, 3.7.3, 3.7.4, 3.7.5, 3.7.6, 3.8, 3.8.0.1, 3.8.0.2, 3.8.1, 3.8.2, 3.8.3, 3.8.4, 3.8.5, 3.8.6, 3.8.7, 3.8.7.1, 3.8.7.2, 3.8.7.3, 3.9, 3.9.0.1, 3.9.0.2, 3.9.0.3, 3.9.1, 3.9.2, 3.10, 3.10.0.1, 3.10.1, 3.10.2, 3.10.3, 4.0, 4.0.1, 4.0.2, 4.0.3, 4.0.4, 4.0.5, 4.0.6, 4.0.7, 4.1, 4.1.1, 4.1.2, 4.1.2.1, 4.2, 4.3, 4.3.1, 4.3.2, 4.3.3, 4.4, 4.4.0.1, 4.4.0.2, 4.5, 4.6, 4.6.0.1, 4.7, 4.7.0.1, 4.8, 4.9, 4.9.1, 4.10, 4.11, 4.11.1, 4.12, 4.12.1, 4.12.2, 4.12.3, 4.13, 4.13.1, 4.13.2, 4.13.2.1, 4.14, 4.15, 4.15.1, 4.15.2, 4.15.3, 4.15.4, 4.16, 4.16.1, 4.17, 4.17.1, 4.18, 4.18.1, 4.19, 4.19.1, 4.19.2, 5, 5.0.1, 5.1, 5.1.1, 5.2 |
---|---|

Dependencies | array (>=0.3.0.2 && <0.5), base (>=4.3 && <5), bytestring (>=0.9.1.10 && <0.10), containers (>=0.4.2 && <0.6), ghc-prim, mtl (>=2.0.1 && <2.2), parallel (>=3.1.0.1 && <3.3), template-haskell (>=2.4 && <2.8), text (>=0.11.1.5 && <0.12), transformers (>=0.2.2 && <0.4) [details] |

License | BSD-3-Clause |

Copyright | Copyright (C) 2012 Edward A. Kmett |

Author | Edward A. Kmett |

Maintainer | Edward A. Kmett <ekmett@gmail.com> |

Category | Data, Lenses |

Home page | http://github.com/ekmett/lens/ |

Bug tracker | http://github.com/ekmett/lens/issues |

Source repo | head: git clone git://github.com/ekmett/lens.git |

Uploaded | by EdwardKmett at 2012-08-03T17:10:35Z |

Distributions | Arch:5.2, Debian:4.18.1, Fedora:4.19.2, FreeBSD:4.12.3, LTSHaskell:5.1.1, NixOS:5.1.1, Stackage:5.2, openSUSE:5.1 |

Reverse Dependencies | 1355 direct, 5060 indirect [details] |

Downloads | 405544 total (876 in the last 30 days) |

Rating | 3.0 (votes: 50) [estimated by Bayesian average] |

Your Rating | |

Status | Docs uploaded by user Build status unknown [no reports yet] |