# The lens package

The combinators in `Control.Lens` provide a highly generic toolbox for composing
families of getters, folds, traversals, setters and lenses.

*Getter*

A ` Getter a c` is just any function

`(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 ` Fold a c` is a generalization of something

`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 ` Traversal a b c d` is a generalization of

`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 ` Setter a b c d` is a generalization of

`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 ` Lens a b c d` is a purely functional reference.

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
` Simple Lens Bar Foo`, just export a function with the signature:

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`.

## Properties

Versions | 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 |
---|---|

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 | BSD3 |

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

Author | Edward A. Kmett |

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

Stability | provisional |

Category | Data, Lenses |

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

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

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

Uploaded | Fri Aug 3 08:20:56 UTC 2012 by EdwardKmett |

Distributions | Arch:4.14, Debian:4.13, FreeBSD:4.12.3, LTSHaskell:4.13, NixOS:4.14, Stackage:4.14 |

Downloads | 129017 total (356 in the last 30 days) |

Votes | |

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

## Modules

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

*GHC**Generics*

*Language**Haskell*

[Index]

## Downloads

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