Portability | Rank2Types |
---|---|

Stability | provisional |

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

Safe Haskell | Safe-Infered |

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`

as Applicative isn't a superclass of
`Gettable`

.

`Functor`

, however is the superclass of both.

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`

.

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`

= `Accessor`

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

when used as a `Traversal`

.

- type Lens a b c d = forall f. Functor f => (c -> f d) -> a -> f b
- type Simple f a b = f a a b b
- lens :: (a -> c) -> (a -> d -> b) -> Lens a b c d
- (%%~) :: LensLike f a b c d -> (c -> f d) -> a -> f b
- (%%=) :: MonadState a m => LensLike ((,) e) a a c d -> (c -> (e, d)) -> m e
- _1 :: Lens (a, c) (b, c) a b
- _2 :: Lens (c, a) (c, b) a b
- resultAt :: Eq e => e -> Simple Lens (e -> a) a
- class Focus st where
- clone :: Functor f => LensLike (IndexedStore c d) a b c d -> (c -> f d) -> a -> f b
- merged :: Functor f => LensLike f a b c c -> LensLike f a' b' c c -> LensLike f (Either a a') (Either b b') c c
- bothLenses :: Lens a b c d -> Lens a' b' c' d' -> Lens (a, a') (b, b') (c, c') (d, d')
- type LensLike f a b c d = (c -> f d) -> a -> f b
- type Overloaded k f a b c d = k (c -> f d) (a -> f b)
- type SimpleLens a b = Lens a a b b
- type SimpleLensLike f a b = LensLike f a a b b
- type SimpleOverloaded k f a b = Overloaded k f a a b b

# Lenses

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

A `Lens`

is actually a lens family as described in http://comonad.com/reader/2012/mirrored-lenses/.

With great power comes great responsibility and a `Lens`

is subject to the three common sense lens laws:

1) You get back what you put in:

view l (set l b a) = b

2) Putting back what you got doesn't change anything:

set l (view l a) a = a

3) Setting twice is the same as setting once:

set l c (set l b a) = set l c a

These laws are strong enough that the 4 type parameters of a `Lens`

cannot vary fully independently. For more on
how they interact, read the Why is it a Lens Family? section of http://comonad.com/reader/2012/mirrored-lenses/.

Every `Lens`

can be used directly as a `Setter`

or `Traversal`

.

You can also use a `Lens`

for `Getting`

as if it were a `Fold`

or `Getter`

.

Since every lens is a valid `Traversal`

, the traversal laws should also apply to any lenses you create.

- ) Idiomatic naturality:

l pure = pure

- ) Sequential composition:

fmap (l f) . l g = getCompose . l (Compose . fmap f . g)

type Lens = forall f. Functor f => LensLike f a b c d

type Simple f a b = f a a b bSource

A

, `Simple`

`Lens`

, ... can be used instead of a `Simple`

`Traversal`

`Lens`

,`Traversal`

, ...
whenever the type variables don't change upon setting a value.

imaginary :: Simple Lens (Complex a) a traverseHead :: Simple Traversal [a] a

Note: To use this alias in your own code with

or `LensLike`

f`Setter`

, you may have to turn on
`LiberalTypeSynonyms`

.

lens :: (a -> c) -> (a -> d -> b) -> Lens a b c dSource

Build a `Lens`

from a getter and a setter.

lens :: Functor f => (a -> c) -> (a -> d -> b) -> (c -> f d) -> a -> f b

(%%~) :: LensLike f a b c d -> (c -> f d) -> a -> f bSource

(`%%~`

) can be used in one of two scenarios:

When applied to a `Lens`

, it can edit the target of the `Lens`

in a structure, extracting a
functorial result.

When applied to a `Traversal`

, it can edit the targets of the `Traversals`

, extracting an
applicative summary of its actions.

For all that the definition of this combinator is just:

(%%~) = id

(%%~) :: Functor f => Iso a b c d -> (c -> f d) -> a -> f b (%%~) :: Functor f => Lens a b c d -> (c -> f d) -> a -> f b (%%~) :: Applicative f => Traversal a b c d -> (c -> f d) -> a -> f b

It may be beneficial to think about it as if it had these even more restrictive types, however:

When applied to a `Traversal`

, it can edit the targets of the `Traversals`

, extracting a
supplemental monoidal summary of its actions, by choosing f = ((,) m)

(%%~) :: Iso a b c d -> (c -> (e, d)) -> a -> (e, b) (%%~) :: Lens a b c d -> (c -> (e, d)) -> a -> (e, b) (%%~) :: Monoid m => Traversal a b c d -> (c -> (m, d)) -> a -> (m, b)

(%%=) :: MonadState a m => LensLike ((,) e) a a c d -> (c -> (e, d)) -> m eSource

Modify the target of a `Lens`

in the current state returning some extra information of `c`

or
modify all targets of a `Traversal`

in the current state, extracting extra information of type `c`

and return a monoidal summary of the changes.

(%%=) = (state.)

It may be useful to think of (`%%=`

), instead, as having either of the following more restricted
type signatures:

(%%=) :: MonadState a m => Iso a a c d -> (c -> (e, d) -> m e (%%=) :: MonadState a m => Lens a a c d -> (c -> (e, d) -> m e (%%=) :: (MonadState a m, Monoid e) => Traversal a a c d -> (c -> (e, d) -> m e

## Common Lenses

_1 :: Lens (a, c) (b, c) a bSource

This is a lens that can change the value (and type) of the first field of a pair.

ghci> (1,2)^._1 1

ghci> _1 +~ "hello" $ (1,2) ("hello",2)

_1 :: Functor f => (a -> f b) -> (a,c) -> f (a,c)

_2 :: Lens (c, a) (c, b) a bSource

As `_1`

, but for the second field of a pair.

anyOf _2 :: (c -> Bool) -> (a, c) -> Bool traverse._2 :: (Applicative f, Traversable t) => (a -> f b) -> t (c, a) -> f (t (c, b)) foldMapOf (traverse._2) :: (Traversable t, Monoid m) => (c -> m) -> t (b, c) -> m

_2 :: Functor f => (a -> f b) -> (c,a) -> f (c,b)

resultAt :: Eq e => e -> Simple Lens (e -> a) aSource

This lens can be used to change the result of a function but only where the arguments match the key given.

# Traversing and Lensing

This class allows us to use `focus`

on a number of different monad transformers.

focus :: Monad m => LensLike (Focusing m c) a a b b -> st b m c -> st a m cSource

Run a monadic action in a larger context than it was defined in, using a `Simple`

`Lens`

or `Simple`

`Traversal`

.

This is commonly used to lift actions in a simpler state monad into a state monad with a larger state type.

When applied to a 'Simple `Traversal`

over multiple values, the actions for each target are executed sequentially
and the results are aggregated monoidally
and a monoidal summary
of the result is given.

focus :: Monad m => Simple Iso a b -> st b m c -> st a m c focus :: Monad m => Simple Lens a b -> st b m c -> st a m c focus :: (Monad m, Monoid c) => Simple Traversal a b -> st b m c -> st a m c

focus_ :: Monad m => LensLike (Focusing m ()) a a b b -> st b m c -> st a m ()Source

Like `focus`

, but discarding any accumulated results as you go.

focus_ :: Monad m => Simple Iso a b -> st b m c -> st a m () focus_ :: Monad m => Simple Lens a b -> st b m c -> st a m () focus_ :: (Monad m, Monoid c) => Simple Traversal a b -> st b m c -> st a m ()

setFocus :: Simple Setter a b -> st b Identity c -> st a Identity ()Source

# Cloning Lenses

clone :: Functor f => LensLike (IndexedStore c d) a b c d -> (c -> f d) -> a -> f bSource

Cloning a `Lens`

is one way to make sure you arent given
something weaker, such as a `Traversal`

and can be used
as a way to pass around lenses that have to be monomorphic in `f`

.

Note: This only accepts a proper `Lens`

, because `IndexedStore`

lacks its
(admissable) Applicative instance.

merged :: Functor f => LensLike f a b c c -> LensLike f a' b' c c -> LensLike f (Either a a') (Either b b') c cSource

Merge two lenses, getters, setters, folds or traversals.

bothLenses :: Lens a b c d -> Lens a' b' c' d' -> Lens (a, a') (b, b') (c, c') (d, d')Source

`bothLenses`

makes a lens from two other lenses (or isomorphisms)

# Simplified and In-Progress

type LensLike f a b c d = (c -> f d) -> a -> f bSource

Many combinators that accept a `Lens`

can also accept a `Traversal`

in limited situations.

They do so by specializing the type of `Functor`

that they require of the caller.

If a function accepts a

for some `LensLike`

f a b c d`Functor`

`f`

, then they may be passed a `Lens`

.

Further, if `f`

is an `Applicative`

, they may also be passed a `Traversal`

.

type Overloaded k f a b c d = k (c -> f d) (a -> f b)Source

type LensLike f a b c d = Overloaded (->) f a b c d

type SimpleLens a b = Lens a a b bSource

type SimpleLens = Simple Lens

type SimpleLensLike f a b = LensLike f a a b bSource

type SimpleLensLike f = Simple (LensLike f)

type SimpleOverloaded k f a b = Overloaded k f a a b bSource

type SimpleOverloaded k f a b = Simple (Overloaded k f) a b