copyright: Copyright (C) 2012-2016 Edward A. Kmett
build-type: Custom
-- build-tools: cpphs
tested-with: GHC == 7.4.2
, GHC == 7.6.3
, GHC == 7.8.4
, GHC == 7.10.3
, GHC == 8.0.2
, GHC == 8.2.2
, GHC == 8.4.4
, GHC == 8.6.4
synopsis: Lenses, Folds and Traversals
description:
This package comes \"Batteries Included\" with many useful lenses for the types
commonly used from the Haskell Platform, and with tools for automatically
generating lenses and isomorphisms for user-supplied data types.
.
The combinators in @Control.Lens@ provide a highly generic toolbox for composing
families of getters, folds, isomorphisms, traversals, setters and lenses and their
indexed variants.
.
An overview, with a large number of examples can be found in the <https://github.com/ekmett/lens#lens-lenses-folds-and-traversals README>.
.
An introductory video on the style of code used in this library by Simon Peyton Jones is available from <http://skillsmatter.com/podcast/scala/lenses-compositional-data-access-and-manipulation Skills Matter>.
.
A video on how to use lenses and how they are constructed is available on <http://youtu.be/cefnmjtAolY?hd=1 youtube>.
.
Slides for that second talk can be obtained from <http://comonad.com/haskell/Lenses-Folds-and-Traversals-NYC.pdf comonad.com>.
.
More information on the care and feeding of lenses, including a brief tutorial and motivation
for their types can be found on the <https://github.com/ekmett/lens/wiki lens wiki>.
.
A small game of @pong@ and other more complex examples that manage their state using lenses can be found in the <https://github.com/ekmett/lens/blob/master/examples/ example folder>.
.
/Lenses, Folds and Traversals/
.
With some signatures simplified, the core of the hierarchy of lens-like constructions looks like:
.
.
<<http://i.imgur.com/ALlbPRa.png>>
.
<Hierarchy.png (Local Copy)>
.
You can compose any two elements of the hierarchy above using @(.)@ from the @Prelude@, and you can
use any element of the hierarchy as any type it linked to above it.
.
The result is their lowest upper bound in the hierarchy (or an error if that bound doesn't exist).
.
For instance:
.
* You can use any 'Traversal' as a 'Fold' or as a 'Setter'.
.
* The composition of a 'Traversal' and a 'Getter' yields a 'Fold'.
.
/Minimizing Dependencies/
.
If you want to provide lenses and traversals for your own types in your own libraries, then you
can do so without incurring a dependency on this (or any other) lens package at all.
.
/e.g./ for a data type:
.
> data Foo a = Foo Int Int a
.
You can define lenses such as
.
> -- bar :: Lens' (Foo a) Int
> bar :: Functor f => (Int -> f Int) -> Foo a -> f (Foo a)
> bar f (Foo a b c) = fmap (\a' -> Foo a' b c) (f a)
.
> -- quux :: Lens (Foo a) (Foo b) a b
> quux :: Functor f => (a -> f b) -> Foo a -> f (Foo b)
> quux f (Foo a b c) = fmap (Foo a b) (f c)
.
without the need to use any type that isn't already defined in the @Prelude@.
.
And you can define a traversal of multiple fields with 'Control.Applicative.Applicative':
.
> -- traverseBarAndBaz :: Traversal' (Foo a) Int
> traverseBarAndBaz :: Applicative f => (Int -> f Int) -> Foo a -> f (Foo a)
> traverseBarAndBaz f (Foo a b c) = Foo <$> f a <*> f b <*> pure c
.
What is provided in this library is a number of stock lenses and traversals for
common haskell types, a wide array of combinators for working them, and more