Copyright | (C) 2012-15 Edward Kmett |
---|---|

License | BSD-style (see the file LICENSE) |

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

Stability | provisional |

Portability | Rank2Types |

Safe Haskell | Safe-Inferred |

Language | Haskell98 |

A

is a purely functional reference.`Lens`

s t a b

While a `Traversal`

could be used for
`Getting`

like a valid `Fold`

, it
wasn't a valid `Getter`

as a
`Getter`

can't require an `Applicative`

constraint.

`Functor`

, however, is a constraint on both.

type`Lens`

s t a b = forall f.`Functor`

f => (a -> f b) -> s -> f t

Every `Lens`

can be used for `Getting`

like a
`Fold`

that doesn't use the `Applicative`

or
`Contravariant`

.

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`

.

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`

.

In the examples below, `getter`

and `setter`

are supplied as example getters
and setters, and are not actual functions supplied by this package.

- type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t
- type Lens' s a = Lens s s a a
- type IndexedLens i s t a b = forall f p. (Indexable i p, Functor f) => p a (f b) -> s -> f t
- type IndexedLens' i s a = IndexedLens i s s a a
- type ALens s t a b = LensLike (Pretext (->) a b) s t a b
- type ALens' s a = ALens s s a a
- type AnIndexedLens i s t a b = Optical (Indexed i) (->) (Pretext (Indexed i) a b) s t a b
- type AnIndexedLens' i s a = AnIndexedLens i s s a a
- lens :: (s -> a) -> (s -> b -> t) -> Lens s t a b
- ilens :: (s -> (i, a)) -> (s -> b -> t) -> IndexedLens i s t a b
- iplens :: (s -> a) -> (s -> b -> t) -> IndexPreservingLens s t a b
- (%%~) :: Optical p q f s t a b -> p a (f b) -> q s (f t)
- (%%=) :: MonadState s m => Over p ((,) r) s s a b -> p a (r, b) -> m r
- (%%@~) :: IndexedLensLike i f s t a b -> (i -> a -> f b) -> s -> f t
- (%%@=) :: MonadState s m => IndexedLensLike i ((,) r) s s a b -> (i -> a -> (r, b)) -> m r
- (<%@~) :: Optical (Indexed i) q ((,) b) s t a b -> (i -> a -> b) -> q s (b, t)
- (<%@=) :: MonadState s m => IndexedLensLike i ((,) b) s s a b -> (i -> a -> b) -> m b
- (<<%@~) :: Optical (Indexed i) q ((,) a) s t a b -> (i -> a -> b) -> q s (a, t)
- (<<%@=) :: MonadState s m => IndexedLensLike i ((,) a) s s a b -> (i -> a -> b) -> m a
- (&) :: a -> (a -> b) -> b
- (<&>) :: Functor f => f a -> (a -> b) -> f b
- (??) :: Functor f => f (a -> b) -> a -> f b
- (&~) :: s -> State s a -> s
- choosing :: Functor f => LensLike f s t a b -> LensLike f s' t' a b -> LensLike f (Either s s') (Either t t') a b
- chosen :: IndexPreservingLens (Either a a) (Either b b) a b
- alongside :: LensLike (AlongsideLeft f b') s t a b -> LensLike (AlongsideRight f t) s' t' a' b' -> LensLike f (s, s') (t, t') (a, a') (b, b')
- inside :: Corepresentable p => ALens s t a b -> Lens (p e s) (p e t) (p e a) (p e b)
- (<%~) :: Profunctor p => Optical p q ((,) b) s t a b -> p a b -> q s (b, t)
- (<+~) :: Num a => Optical (->) q ((,) a) s t a a -> a -> q s (a, t)
- (<-~) :: Num a => Optical (->) q ((,) a) s t a a -> a -> q s (a, t)
- (<*~) :: Num a => Optical (->) q ((,) a) s t a a -> a -> q s (a, t)
- (<//~) :: Fractional a => Optical (->) q ((,) a) s t a a -> a -> q s (a, t)
- (<^~) :: (Num a, Integral e) => Optical (->) q ((,) a) s t a a -> e -> q s (a, t)
- (<^^~) :: (Fractional a, Integral e) => Optical (->) q ((,) a) s t a a -> e -> q s (a, t)
- (<**~) :: Floating a => Optical (->) q ((,) a) s t a a -> a -> q s (a, t)
- (<||~) :: Optical (->) q ((,) Bool) s t Bool Bool -> Bool -> q s (Bool, t)
- (<&&~) :: Optical (->) q ((,) Bool) s t Bool Bool -> Bool -> q s (Bool, t)
- (<<>~) :: Monoid m => Optical (->) q ((,) m) s t m m -> m -> q s (m, t)
- (<<%~) :: Strong p => Optical p q ((,) a) s t a b -> p a b -> q s (a, t)
- (<<.~) :: Optical (->) q ((,) a) s t a b -> b -> q s (a, t)
- (<<+~) :: Num a => Optical' (->) q ((,) a) s a -> a -> q s (a, s)
- (<<-~) :: Num a => Optical' (->) q ((,) a) s a -> a -> q s (a, s)
- (<<*~) :: Num a => Optical' (->) q ((,) a) s a -> a -> q s (a, s)
- (<<//~) :: Fractional a => Optical' (->) q ((,) a) s a -> a -> q s (a, s)
- (<<^~) :: (Num a, Integral e) => Optical' (->) q ((,) a) s a -> e -> q s (a, s)
- (<<^^~) :: (Fractional a, Integral e) => Optical' (->) q ((,) a) s a -> e -> q s (a, s)
- (<<**~) :: Floating a => Optical' (->) q ((,) a) s a -> a -> q s (a, s)
- (<<||~) :: Optical' (->) q ((,) Bool) s Bool -> Bool -> q s (Bool, s)
- (<<&&~) :: Optical' (->) q ((,) Bool) s Bool -> Bool -> q s (Bool, s)
- (<<<>~) :: Monoid r => Optical' (->) q ((,) r) s r -> r -> q s (r, s)
- (<%=) :: (Profunctor p, MonadState s m) => Over p ((,) b) s s a b -> p a b -> m b
- (<+=) :: (MonadState s m, Num a) => LensLike' ((,) a) s a -> a -> m a
- (<-=) :: (MonadState s m, Num a) => LensLike' ((,) a) s a -> a -> m a
- (<*=) :: (MonadState s m, Num a) => LensLike' ((,) a) s a -> a -> m a
- (<//=) :: (MonadState s m, Fractional a) => LensLike' ((,) a) s a -> a -> m a
- (<^=) :: (MonadState s m, Num a, Integral e) => LensLike' ((,) a) s a -> e -> m a
- (<^^=) :: (MonadState s m, Fractional a, Integral e) => LensLike' ((,) a) s a -> e -> m a
- (<**=) :: (MonadState s m, Floating a) => LensLike' ((,) a) s a -> a -> m a
- (<||=) :: MonadState s m => LensLike' ((,) Bool) s Bool -> Bool -> m Bool
- (<&&=) :: MonadState s m => LensLike' ((,) Bool) s Bool -> Bool -> m Bool
- (<<>=) :: (MonadState s m, Monoid r) => LensLike' ((,) r) s r -> r -> m r
- (<<%=) :: (Strong p, MonadState s m) => Over p ((,) a) s s a b -> p a b -> m a
- (<<.=) :: MonadState s m => LensLike ((,) a) s s a b -> b -> m a
- (<<+=) :: (MonadState s m, Num a) => LensLike' ((,) a) s a -> a -> m a
- (<<-=) :: (MonadState s m, Num a) => LensLike' ((,) a) s a -> a -> m a
- (<<*=) :: (MonadState s m, Num a) => LensLike' ((,) a) s a -> a -> m a
- (<<//=) :: (MonadState s m, Fractional a) => LensLike' ((,) a) s a -> a -> m a
- (<<^=) :: (MonadState s m, Num a, Integral e) => LensLike' ((,) a) s a -> e -> m a
- (<<^^=) :: (MonadState s m, Fractional a, Integral e) => LensLike' ((,) a) s a -> e -> m a
- (<<**=) :: (MonadState s m, Floating a) => LensLike' ((,) a) s a -> a -> m a
- (<<||=) :: MonadState s m => LensLike' ((,) Bool) s Bool -> Bool -> m Bool
- (<<&&=) :: MonadState s m => LensLike' ((,) Bool) s Bool -> Bool -> m Bool
- (<<<>=) :: (MonadState s m, Monoid r) => LensLike' ((,) r) s r -> r -> m r
- (<<~) :: MonadState s m => ALens s s a b -> m b -> m b
- cloneLens :: ALens s t a b -> Lens s t a b
- cloneIndexPreservingLens :: ALens s t a b -> IndexPreservingLens s t a b
- cloneIndexedLens :: AnIndexedLens i s t a b -> IndexedLens i s t a b
- overA :: Arrow ar => LensLike (Context a b) s t a b -> ar a b -> ar s t
- storing :: ALens s t a b -> b -> s -> t
- (^#) :: s -> ALens s t a b -> a
- (#~) :: ALens s t a b -> b -> s -> t
- (#%~) :: ALens s t a b -> (a -> b) -> s -> t
- (#%%~) :: Functor f => ALens s t a b -> (a -> f b) -> s -> f t
- (<#~) :: ALens s t a b -> b -> s -> (b, t)
- (<#%~) :: ALens s t a b -> (a -> b) -> s -> (b, t)
- (#=) :: MonadState s m => ALens s s a b -> b -> m ()
- (#%=) :: MonadState s m => ALens s s a b -> (a -> b) -> m ()
- (#%%=) :: MonadState s m => ALens s s a b -> (a -> (r, b)) -> m r
- (<#=) :: MonadState s m => ALens s s a b -> b -> m b
- (<#%=) :: MonadState s m => ALens s s a b -> (a -> b) -> m b
- devoid :: Over p f Void Void a b
- united :: Lens' a ()
- data Context a b t = Context (b -> t) a
- type Context' a = Context a a
- locus :: IndexedComonadStore p => Lens (p a c s) (p b c s) a b
- fusing :: Functor f => LensLike (Yoneda f) s t a b -> LensLike f s t a b

# Lenses

type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t Source

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 v s) ≡ v

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

`set`

l (`view`

l s) s ≡ s

3) Setting twice is the same as setting once:

`set`

l v' (`set`

l v s) ≡`set`

l v' s

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

There are some emergent properties of these laws:

1)

must be injective for every `set`

l s`s`

This is a consequence of law #1

2)

must be surjective, because of law #2, which indicates that it is possible to obtain any `set`

l`v`

from some `s`

such that `set`

s v = s

3) Given just the first two laws you can prove a weaker form of law #3 where the values `v`

that you are setting match:

`set`

l v (`set`

l v s) ≡`set`

l v s

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 are required of any `Lens`

you create:

l`pure`

≡`pure`

`fmap`

(l f)`.`

l g ≡`getCompose`

`.`

l (`Compose`

`.`

`fmap`

f`.`

g)

type`Lens`

s t a b = forall f.`Functor`

f =>`LensLike`

f s t a b

type IndexedLens i s t a b = forall f p. (Indexable i p, Functor f) => p a (f b) -> s -> f t Source

Every `IndexedLens`

is a valid `Lens`

and a valid `IndexedTraversal`

.

type IndexedLens' i s a = IndexedLens i s s a a Source

type`IndexedLens'`

i =`Simple`

(`IndexedLens`

i)

## Concrete Lenses

type AnIndexedLens i s t a b = Optical (Indexed i) (->) (Pretext (Indexed i) a b) s t a b Source

When you see this as an argument to a function, it expects an `IndexedLens`

type AnIndexedLens' i s a = AnIndexedLens i s s a a Source

type`AnIndexedLens'`

=`Simple`

(`AnIndexedLens`

i)

# Combinators

ilens :: (s -> (i, a)) -> (s -> b -> t) -> IndexedLens i s t a b Source

Build an `IndexedLens`

from a `Getter`

and
a `Setter`

.

iplens :: (s -> a) -> (s -> b -> t) -> IndexPreservingLens s t a b Source

(%%~) :: Optical p q f s t a b -> p a (f b) -> q s (f t) infixr 4 Source

(`%%~`

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

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

(`%%~`

) ::`Functor`

f =>`Iso`

s t a b -> (a -> f b) -> s -> f t (`%%~`

) ::`Functor`

f =>`Lens`

s t a b -> (a -> f b) -> s -> f t (`%%~`

) ::`Applicative`

f =>`Traversal`

s t a b -> (a -> f b) -> s -> f t

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`

s t a b -> (a -> (r, b)) -> s -> (r, t) (`%%~`

) ::`Lens`

s t a b -> (a -> (r, b)) -> s -> (r, t) (`%%~`

) ::`Monoid`

m =>`Traversal`

s t a b -> (a -> (m, b)) -> s -> (m, t)

(%%=) :: MonadState s m => Over p ((,) r) s s a b -> p a (r, b) -> m r infix 4 Source

Modify the target of a `Lens`

in the current state returning some extra
information of type `r`

or modify all targets of a
`Traversal`

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

and return a monoidal summary of the changes.

`>>>`

(f a,(g a,b))`runState (_1 %%= \x -> (f x, g x)) (a,b)`

(`%%=`

) ≡ (`state`

`.`

)

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

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

(`%%=`

) ::`MonadState`

s m =>`Iso`

s s a b -> (a -> (r, b)) -> m r (`%%=`

) ::`MonadState`

s m =>`Lens`

s s a b -> (a -> (r, b)) -> m r (`%%=`

) :: (`MonadState`

s m,`Monoid`

r) =>`Traversal`

s s a b -> (a -> (r, b)) -> m r

(%%@~) :: IndexedLensLike i f s t a b -> (i -> a -> f b) -> s -> f t infixr 4 Source

Adjust the target of an `IndexedLens`

returning a supplementary result, or
adjust all of the targets of an `IndexedTraversal`

and return a monoidal summary
of the supplementary results and the answer.

(`%%@~`

) ≡`withIndex`

(`%%@~`

) ::`Functor`

f =>`IndexedLens`

i s t a b -> (i -> a -> f b) -> s -> f t (`%%@~`

) ::`Applicative`

f =>`IndexedTraversal`

i s t a b -> (i -> a -> f b) -> s -> f t

In particular, it is often useful to think of this function as having one of these even more restricted type signatures:

(`%%@~`

) ::`IndexedLens`

i s t a b -> (i -> a -> (r, b)) -> s -> (r, t) (`%%@~`

) ::`Monoid`

r =>`IndexedTraversal`

i s t a b -> (i -> a -> (r, b)) -> s -> (r, t)

(%%@=) :: MonadState s m => IndexedLensLike i ((,) r) s s a b -> (i -> a -> (r, b)) -> m r infix 4 Source

Adjust the target of an `IndexedLens`

returning a supplementary result, or
adjust all of the targets of an `IndexedTraversal`

within the current state, and
return a monoidal summary of the supplementary results.

l`%%@=`

f ≡`state`

(l`%%@~`

f)

(`%%@=`

) ::`MonadState`

s m =>`IndexedLens`

i s s a b -> (i -> a -> (r, b)) -> s -> m r (`%%@=`

) :: (`MonadState`

s m,`Monoid`

r) =>`IndexedTraversal`

i s s a b -> (i -> a -> (r, b)) -> s -> m r

(<%@~) :: Optical (Indexed i) q ((,) b) s t a b -> (i -> a -> b) -> q s (b, t) infixr 4 Source

Adjust the target of an `IndexedLens`

returning the intermediate result, or
adjust all of the targets of an `IndexedTraversal`

and return a monoidal summary
along with the answer.

l`<%~`

f ≡ l`<%@~`

`const`

f

When you do not need access to the index then (`<%~`

) is more liberal in what it can accept.

If you do not need the intermediate result, you can use (`%@~`

) or even (`%~`

).

(`<%@~`

) ::`IndexedLens`

i s t a b -> (i -> a -> b) -> s -> (b, t) (`<%@~`

) ::`Monoid`

b =>`IndexedTraversal`

i s t a b -> (i -> a -> b) -> s -> (b, t)

(<%@=) :: MonadState s m => IndexedLensLike i ((,) b) s s a b -> (i -> a -> b) -> m b infix 4 Source

Adjust the target of an `IndexedLens`

returning the intermediate result, or
adjust all of the targets of an `IndexedTraversal`

within the current state, and
return a monoidal summary of the intermediate results.

(`<%@=`

) ::`MonadState`

s m =>`IndexedLens`

i s s a b -> (i -> a -> b) -> m b (`<%@=`

) :: (`MonadState`

s m,`Monoid`

b) =>`IndexedTraversal`

i s s a b -> (i -> a -> b) -> m b

(<<%@~) :: Optical (Indexed i) q ((,) a) s t a b -> (i -> a -> b) -> q s (a, t) infixr 4 Source

Adjust the target of an `IndexedLens`

returning the old value, or
adjust all of the targets of an `IndexedTraversal`

and return a monoidal summary
of the old values along with the answer.

(`<<%@~`

) ::`IndexedLens`

i s t a b -> (i -> a -> b) -> s -> (a, t) (`<<%@~`

) ::`Monoid`

a =>`IndexedTraversal`

i s t a b -> (i -> a -> b) -> s -> (a, t)

(<<%@=) :: MonadState s m => IndexedLensLike i ((,) a) s s a b -> (i -> a -> b) -> m a infix 4 Source

Adjust the target of an `IndexedLens`

returning the old value, or
adjust all of the targets of an `IndexedTraversal`

within the current state, and
return a monoidal summary of the old values.

(`<<%@=`

) ::`MonadState`

s m =>`IndexedLens`

i s s a b -> (i -> a -> b) -> m a (`<<%@=`

) :: (`MonadState`

s m,`Monoid`

b) =>`IndexedTraversal`

i s s a b -> (i -> a -> b) -> m a

## General Purpose Combinators

(&) :: a -> (a -> b) -> b infixl 1 Source

Passes the result of the left side to the function on the right side (forward pipe operator).

This is the flipped version of (`$`

), which is more common in languages like F# as (`|>`

) where it is needed
for inference. Here it is supplied for notational convenience and given a precedence that allows it
to be nested inside uses of (`$`

).

`>>>`

f a`a & f`

`>>>`

6`"hello" & length & succ`

This combinator is commonly used when applying multiple `Lens`

operations in sequence.

`>>>`

("jelly","world")`("hello","world") & _1.element 0 .~ 'j' & _1.element 4 .~ 'y'`

This reads somewhat similar to:

`>>>`

("jelly","world")`flip execState ("hello","world") $ do _1.element 0 .= 'j'; _1.element 4 .= 'y'`

(??) :: Functor f => f (a -> b) -> a -> f b infixl 1 Source

This is convenient to `flip`

argument order of composite functions.

`>>>`

("hello",5)`over _2 ?? ("hello","world") $ length`

`>>>`

("hello",5)`over ?? length ?? ("hello","world") $ _2`

(&~) :: s -> State s a -> s infixl 1 Source

This can be used to chain lens operations using `op=`

syntax
rather than `op~`

syntax for simple non-type-changing cases.

`>>>`

(30,40)`(10,20) & _1 .~ 30 & _2 .~ 40`

`>>>`

(30,40)`(10,20) &~ do _1 .= 30; _2 .= 40`

This does not support type-changing assignment, *e.g.*

`>>>`

("hello",20)`(10,20) & _1 .~ "hello"`

# Lateral Composition

choosing :: Functor f => LensLike f s t a b -> LensLike f s' t' a b -> LensLike f (Either s s') (Either t t') a b Source

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

`chosen`

≡`choosing`

`id`

`id`

`choosing`

::`Getter`

s a ->`Getter`

s' a ->`Getter`

(`Either`

s s') a`choosing`

::`Fold`

s a ->`Fold`

s' a ->`Fold`

(`Either`

s s') a`choosing`

::`Lens'`

s a ->`Lens'`

s' a ->`Lens'`

(`Either`

s s') a`choosing`

::`Traversal'`

s a ->`Traversal'`

s' a ->`Traversal'`

(`Either`

s s') a`choosing`

::`Setter'`

s a ->`Setter'`

s' a ->`Setter'`

(`Either`

s s') a

chosen :: IndexPreservingLens (Either a a) (Either b b) a b Source

This is a `Lens`

that updates either side of an `Either`

, where both sides have the same type.

`chosen`

≡`choosing`

`id`

`id`

`>>>`

a`Left a^.chosen`

`>>>`

a`Right a^.chosen`

`>>>`

"hello"`Right "hello"^.chosen`

`>>>`

Right (a * b)`Right a & chosen *~ b`

`chosen`

::`Lens`

(`Either`

a a) (`Either`

b b) a b`chosen`

f (`Left`

a) =`Left`

`<$>`

f a`chosen`

f (`Right`

a) =`Right`

`<$>`

f a

alongside :: LensLike (AlongsideLeft f b') s t a b -> LensLike (AlongsideRight f t) s' t' a' b' -> LensLike f (s, s') (t, t') (a, a') (b, b') Source

`alongside`

makes a `Lens`

from two other lenses or a `Getter`

from two other getters
by executing them on their respective halves of a product.

`>>>`

(a,b)`(Left a, Right b)^.alongside chosen chosen`

`>>>`

(Left c,Right d)`(Left a, Right b) & alongside chosen chosen .~ (c,d)`

`alongside`

::`Lens`

s t a b ->`Lens`

s' t' a' b' ->`Lens`

(s,s') (t,t') (a,a') (b,b')`alongside`

::`Getter`

s t a b ->`Getter`

s' t' a' b' ->`Getter`

(s,s') (t,t') (a,a') (b,b')

# Setting Functionally with Passthrough

(<%~) :: Profunctor p => Optical p q ((,) b) s t a b -> p a b -> q s (b, t) infixr 4 Source

(<//~) :: Fractional a => Optical (->) q ((,) a) s t a a -> a -> q s (a, t) infixr 4 Source

Divide the target of a fractionally valued `Lens`

and return the result.

When you do not need the result of the division, (`//~`

) is more flexible.

(`<//~`

) ::`Fractional`

a =>`Lens'`

s a -> a -> s -> (a, s) (`<//~`

) ::`Fractional`

a =>`Iso'`

s a -> a -> s -> (a, s)

(<^^~) :: (Fractional a, Integral e) => Optical (->) q ((,) a) s t a a -> e -> q s (a, t) infixr 4 Source

Raise the target of a fractionally valued `Lens`

to an `Integral`

power
and return the result.

When you do not need the result of the operation, (`^^~`

) is more flexible.

(`<^^~`

) :: (`Fractional`

a,`Integral`

e) =>`Lens'`

s a -> e -> s -> (a, s) (`<^^~`

) :: (`Fractional`

a,`Integral`

e) =>`Iso'`

s a -> e -> s -> (a, s)

(<<+~) :: Num a => Optical' (->) q ((,) a) s a -> a -> q s (a, s) infixr 4 Source

Increment the target of a numerically valued `Lens`

and return the old value.

When you do not need the old value, (`+~`

) is more flexible.

`>>>`

(a,(a + c,b))`(a,b) & _1 <<+~ c`

`>>>`

(b,(a,b + c))`(a,b) & _2 <<+~ c`

(`<<+~`

) ::`Num`

a =>`Lens'`

s a -> a -> s -> (a, s) (`<<+~`

) ::`Num`

a =>`Iso'`

s a -> a -> s -> (a, s)

(<<-~) :: Num a => Optical' (->) q ((,) a) s a -> a -> q s (a, s) infixr 4 Source

Decrement the target of a numerically valued `Lens`

and return the old value.

When you do not need the old value, (`-~`

) is more flexible.

`>>>`

(a,(a - c,b))`(a,b) & _1 <<-~ c`

`>>>`

(b,(a,b - c))`(a,b) & _2 <<-~ c`

(`<<-~`

) ::`Num`

a =>`Lens'`

s a -> a -> s -> (a, s) (`<<-~`

) ::`Num`

a =>`Iso'`

s a -> a -> s -> (a, s)

(<<*~) :: Num a => Optical' (->) q ((,) a) s a -> a -> q s (a, s) infixr 4 Source

Multiply the target of a numerically valued `Lens`

and return the old value.

When you do not need the old value, (`-~`

) is more flexible.

`>>>`

(a,(a * c,b))`(a,b) & _1 <<*~ c`

`>>>`

(b,(a,b * c))`(a,b) & _2 <<*~ c`

(`<<*~`

) ::`Num`

a =>`Lens'`

s a -> a -> s -> (a, s) (`<<*~`

) ::`Num`

a =>`Iso'`

s a -> a -> s -> (a, s)

(<<//~) :: Fractional a => Optical' (->) q ((,) a) s a -> a -> q s (a, s) infixr 4 Source

Divide the target of a numerically valued `Lens`

and return the old value.

When you do not need the old value, (`//~`

) is more flexible.

`>>>`

(a,(a / c,b))`(a,b) & _1 <<//~ c`

`>>>`

(10.0,("Hawaii",5.0))`("Hawaii",10) & _2 <<//~ 2`

(`<<//~`

) :: Fractional a =>`Lens'`

s a -> a -> s -> (a, s) (`<<//~`

) :: Fractional a =>`Iso'`

s a -> a -> s -> (a, s)

(<<^^~) :: (Fractional a, Integral e) => Optical' (->) q ((,) a) s a -> e -> q s (a, s) infixr 4 Source

Raise the target of a fractionally valued `Lens`

to an integral power and return the old value.

When you do not need the old value, (`^^~`

) is more flexible.

(`<<^^~`

) :: (`Fractional`

a,`Integral`

e) =>`Lens'`

s a -> e -> s -> (a, s) (`<<^^~`

) :: (`Fractional`

a,`Integral`

e) =>`Iso'`

s a -> e -> S -> (a, s)

(<<**~) :: Floating a => Optical' (->) q ((,) a) s a -> a -> q s (a, s) infixr 4 Source

Raise the target of a floating-point valued `Lens`

to an arbitrary power and return the old value.

When you do not need the old value, (`**~`

) is more flexible.

`>>>`

(a,(a**c,b))`(a,b) & _1 <<**~ c`

`>>>`

(b,(a,b**c))`(a,b) & _2 <<**~ c`

(`<<**~`

) ::`Floating`

a =>`Lens'`

s a -> a -> s -> (a, s) (`<<**~`

) ::`Floating`

a =>`Iso'`

s a -> a -> s -> (a, s)

(<<||~) :: Optical' (->) q ((,) Bool) s Bool -> Bool -> q s (Bool, s) infixr 4 Source

Logically `||`

the target of a `Bool`

-valued `Lens`

and return the old value.

When you do not need the old value, (`||~`

) is more flexible.

`>>>`

(False,(True,6))`(False,6) & _1 <<||~ True`

`>>>`

(True,("hello",True))`("hello",True) & _2 <<||~ False`

(`<<||~`

) ::`Lens'`

s`Bool`

->`Bool`

-> s -> (`Bool`

, s) (`<<||~`

) ::`Iso'`

s`Bool`

->`Bool`

-> s -> (`Bool`

, s)

(<<&&~) :: Optical' (->) q ((,) Bool) s Bool -> Bool -> q s (Bool, s) infixr 4 Source

Logically `&&`

the target of a `Bool`

-valued `Lens`

and return the old value.

When you do not need the old value, (`&&~`

) is more flexible.

`>>>`

(False,(False,6))`(False,6) & _1 <<&&~ True`

`>>>`

(True,("hello",False))`("hello",True) & _2 <<&&~ False`

(`<<&&~`

) ::`Lens'`

s Bool -> Bool -> s -> (Bool, s) (`<<&&~`

) ::`Iso'`

s Bool -> Bool -> s -> (Bool, s)

(<<<>~) :: Monoid r => Optical' (->) q ((,) r) s r -> r -> q s (r, s) infixr 4 Source

Modify the target of a monoidally valued `Lens`

by `mappend`

ing a new value and return the old value.

When you do not need the old value, (`<>~`

) is more flexible.

`>>>`

(Sum {getSum = a},(Sum {getSum = a + c},b))`(Sum a,b) & _1 <<<>~ Sum c`

`>>>`

("Bond",("James","Bond, 007"))`_2 <<<>~ ", 007" $ ("James", "Bond")`

(`<<<>~`

) ::`Monoid`

r =>`Lens'`

s r -> r -> s -> (r, s) (`<<<>~`

) ::`Monoid`

r =>`Iso'`

s r -> r -> s -> (r, s)

# Setting State with Passthrough

(<%=) :: (Profunctor p, MonadState s m) => Over p ((,) b) s s a b -> p a b -> m b infix 4 Source

Modify the target of a `Lens`

into your `Monad'`

s state by a user supplied
function and return the result.

When applied to a `Traversal`

, it this will return a monoidal summary of all of the intermediate
results.

When you do not need the result of the operation, (`%=`

) is more flexible.

(`<%=`

) ::`MonadState`

s m =>`Lens'`

s a -> (a -> a) -> m a (`<%=`

) ::`MonadState`

s m =>`Iso'`

s a -> (a -> a) -> m a (`<%=`

) :: (`MonadState`

s m,`Monoid`

a) =>`Traversal'`

s a -> (a -> a) -> m a

(<//=) :: (MonadState s m, Fractional a) => LensLike' ((,) a) s a -> a -> m a infix 4 Source

Divide the target of a fractionally valued `Lens`

into your `Monad'`

s state
and return the result.

When you do not need the result of the division, (`//=`

) is more flexible.

(`<//=`

) :: (`MonadState`

s m,`Fractional`

a) =>`Lens'`

s a -> a -> m a (`<//=`

) :: (`MonadState`

s m,`Fractional`

a) =>`Iso'`

s a -> a -> m a

(<^=) :: (MonadState s m, Num a, Integral e) => LensLike' ((,) a) s a -> e -> m a infix 4 Source

Raise the target of a numerically valued `Lens`

into your `Monad'`

s state
to a non-negative `Integral`

power and return the result.

When you do not need the result of the operation, (`^=`

) is more flexible.

(`<^=`

) :: (`MonadState`

s m,`Num`

a,`Integral`

e) =>`Lens'`

s a -> e -> m a (`<^=`

) :: (`MonadState`

s m,`Num`

a,`Integral`

e) =>`Iso'`

s a -> e -> m a

(<^^=) :: (MonadState s m, Fractional a, Integral e) => LensLike' ((,) a) s a -> e -> m a infix 4 Source

Raise the target of a fractionally valued `Lens`

into your `Monad'`

s state
to an `Integral`

power and return the result.

When you do not need the result of the operation, (`^^=`

) is more flexible.

(`<^^=`

) :: (`MonadState`

s m,`Fractional`

b,`Integral`

e) =>`Lens'`

s a -> e -> m a (`<^^=`

) :: (`MonadState`

s m,`Fractional`

b,`Integral`

e) =>`Iso'`

s a -> e -> m a

(<**=) :: (MonadState s m, Floating a) => LensLike' ((,) a) s a -> a -> m a infix 4 Source

Raise the target of a floating-point valued `Lens`

into your `Monad'`

s
state to an arbitrary power and return the result.

When you do not need the result of the operation, (`**=`

) is more flexible.

(`<**=`

) :: (`MonadState`

s m,`Floating`

a) =>`Lens'`

s a -> a -> m a (`<**=`

) :: (`MonadState`

s m,`Floating`

a) =>`Iso'`

s a -> a -> m a

(<<%=) :: (Strong p, MonadState s m) => Over p ((,) a) s s a b -> p a b -> m a infix 4 Source

Modify the target of a `Lens`

into your `Monad'`

s state by a user supplied
function and return the *old* value that was replaced.

When applied to a `Traversal`

, it this will return a monoidal summary of all of the old values
present.

When you do not need the result of the operation, (`%=`

) is more flexible.

(`<<%=`

) ::`MonadState`

s m =>`Lens'`

s a -> (a -> a) -> m a (`<<%=`

) ::`MonadState`

s m =>`Iso'`

s a -> (a -> a) -> m a (`<<%=`

) :: (`MonadState`

s m,`Monoid`

b) =>`Traversal'`

s a -> (a -> a) -> m a

(`<<%=`

) ::`MonadState`

s m =>`LensLike`

((,)a) s s a b -> (a -> b) -> m a

(<<.=) :: MonadState s m => LensLike ((,) a) s s a b -> b -> m a infix 4 Source

Replace the target of a `Lens`

into your `Monad'`

s state with a user supplied
value and return the *old* value that was replaced.

When applied to a `Traversal`

, it this will return a monoidal summary of all of the old values
present.

When you do not need the result of the operation, (`.=`

) is more flexible.

(`<<.=`

) ::`MonadState`

s m =>`Lens'`

s a -> a -> m a (`<<.=`

) ::`MonadState`

s m =>`Iso'`

s a -> a -> m a (`<<.=`

) :: (`MonadState`

s m,`Monoid`

t) =>`Traversal'`

s a -> a -> m a

(<<+=) :: (MonadState s m, Num a) => LensLike' ((,) a) s a -> a -> m a infix 4 Source

Modify the target of a `Lens`

into your `Monad'`

s state by adding a value
and return the *old* value that was replaced.

When you do not need the result of the operation, (`+=`

) is more flexible.

(`<<+=`

) :: (`MonadState`

s m,`Num`

a) =>`Lens'`

s a -> a -> m a (`<<+=`

) :: (`MonadState`

s m,`Num`

a) =>`Iso'`

s a -> a -> m a

(<<-=) :: (MonadState s m, Num a) => LensLike' ((,) a) s a -> a -> m a infix 4 Source

Modify the target of a `Lens`

into your `Monad'`

s state by subtracting a value
and return the *old* value that was replaced.

When you do not need the result of the operation, (`-=`

) is more flexible.

(`<<-=`

) :: (`MonadState`

s m,`Num`

a) =>`Lens'`

s a -> a -> m a (`<<-=`

) :: (`MonadState`

s m,`Num`

a) =>`Iso'`

s a -> a -> m a

(<<*=) :: (MonadState s m, Num a) => LensLike' ((,) a) s a -> a -> m a infix 4 Source

Modify the target of a `Lens`

into your `Monad'`

s state by multipling a value
and return the *old* value that was replaced.

When you do not need the result of the operation, (`*=`

) is more flexible.

(`<<*=`

) :: (`MonadState`

s m,`Num`

a) =>`Lens'`

s a -> a -> m a (`<<*=`

) :: (`MonadState`

s m,`Num`

a) =>`Iso'`

s a -> a -> m a

(<<//=) :: (MonadState s m, Fractional a) => LensLike' ((,) a) s a -> a -> m a infix 4 Source

Modify the target of a `Lens`

into your `Monad`

s state by dividing by a value
and return the *old* value that was replaced.

When you do not need the result of the operation, (`//=`

) is more flexible.

(`<<//=`

) :: (`MonadState`

s m,`Fractional`

a) =>`Lens'`

s a -> a -> m a (`<<//=`

) :: (`MonadState`

s m,`Fractional`

a) =>`Iso'`

s a -> a -> m a

(<<^=) :: (MonadState s m, Num a, Integral e) => LensLike' ((,) a) s a -> e -> m a infix 4 Source

Modify the target of a `Lens`

into your `Monad'`

s state by raising it by a non-negative power
and return the *old* value that was replaced.

When you do not need the result of the operation, (`^=`

) is more flexible.

(`<<^=`

) :: (`MonadState`

s m,`Num`

a,`Integral`

e) =>`Lens'`

s a -> e -> m a (`<<^=`

) :: (`MonadState`

s m,`Num`

a,`Integral`

e) =>`Iso'`

s a -> a -> m a

(<<^^=) :: (MonadState s m, Fractional a, Integral e) => LensLike' ((,) a) s a -> e -> m a infix 4 Source

Modify the target of a `Lens`

into your `Monad'`

s state by raising it by an integral power
and return the *old* value that was replaced.

When you do not need the result of the operation, (`^^=`

) is more flexible.

(`<<^^=`

) :: (`MonadState`

s m,`Fractional`

a,`Integral`

e) =>`Lens'`

s a -> e -> m a (`<<^^=`

) :: (`MonadState`

s m,`Fractional`

a,`Integral`

e) =>`Iso'`

s a -> e -> m a

(<<**=) :: (MonadState s m, Floating a) => LensLike' ((,) a) s a -> a -> m a infix 4 Source

Modify the target of a `Lens`

into your `Monad'`

s state by raising it by an arbitrary power
and return the *old* value that was replaced.

When you do not need the result of the operation, (`**=`

) is more flexible.

(`<<**=`

) :: (`MonadState`

s m,`Floating`

a) =>`Lens'`

s a -> a -> m a (`<<**=`

) :: (`MonadState`

s m,`Floating`

a) =>`Iso'`

s a -> a -> m a

(<<||=) :: MonadState s m => LensLike' ((,) Bool) s Bool -> Bool -> m Bool infix 4 Source

Modify the target of a `Lens`

into your `Monad'`

s state by taking its logical `||`

with a value
and return the *old* value that was replaced.

When you do not need the result of the operation, (`||=`

) is more flexible.

(`<<||=`

) ::`MonadState`

s m =>`Lens'`

s`Bool`

->`Bool`

-> m`Bool`

(`<<||=`

) ::`MonadState`

s m =>`Iso'`

s`Bool`

->`Bool`

-> m`Bool`

(<<&&=) :: MonadState s m => LensLike' ((,) Bool) s Bool -> Bool -> m Bool infix 4 Source

Modify the target of a `Lens`

into your `Monad'`

s state by taking its logical `&&`

with a value
and return the *old* value that was replaced.

When you do not need the result of the operation, (`&&=`

) is more flexible.

(`<<&&=`

) ::`MonadState`

s m =>`Lens'`

s`Bool`

->`Bool`

-> m`Bool`

(`<<&&=`

) ::`MonadState`

s m =>`Iso'`

s`Bool`

->`Bool`

-> m`Bool`

(<<<>=) :: (MonadState s m, Monoid r) => LensLike' ((,) r) s r -> r -> m r infix 4 Source

Modify the target of a `Lens`

into your `Monad'`

s state by `mappend`

ing a value
and return the *old* value that was replaced.

When you do not need the result of the operation, (`<>=`

) is more flexible.

(`<<<>=`

) :: (`MonadState`

s m,`Monoid`

r) =>`Lens'`

s r -> r -> m r (`<<<>=`

) :: (`MonadState`

s m,`Monoid`

r) =>`Iso'`

s r -> r -> m r

(<<~) :: MonadState s m => ALens s s a b -> m b -> m b infixr 2 Source

Run a monadic action, and set the target of `Lens`

to its result.

(`<<~`

) ::`MonadState`

s m =>`Iso`

s s a b -> m b -> m b (`<<~`

) ::`MonadState`

s m =>`Lens`

s s a b -> m b -> m b

NB: This is limited to taking an actual `Lens`

than admitting a `Traversal`

because
there are potential loss of state issues otherwise.

# Cloning Lenses

cloneLens :: ALens s t a b -> Lens s t a b Source

Cloning a `Lens`

is one way to make sure you aren't 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`

.

`>>>`

("hello",2,"you")`let example l x = set (cloneLens l) (x^.cloneLens l + 1) x in example _2 ("hello",1,"you")`

cloneIndexPreservingLens :: ALens s t a b -> IndexPreservingLens s t a b Source

Clone a `Lens`

as an `IndexedPreservingLens`

that just passes through whatever
index is on any `IndexedLens`

, `IndexedFold`

, `IndexedGetter`

or `IndexedTraversal`

it is composed with.

cloneIndexedLens :: AnIndexedLens i s t a b -> IndexedLens i s t a b Source

Clone an `IndexedLens`

as an `IndexedLens`

with the same index.

# Arrow operators

# ALens Combinators

# Common Lenses

We can always retrieve a `()`

from any type.

`>>>`

()`"hello"^.united`

`>>>`

"hello"`"hello" & united .~ ()`

# Context

The indexed store can be used to characterize a `Lens`

and is used by `clone`

.

is isomorphic to
`Context`

a b t`newtype `

,
and to `Context`

a b t = `Context`

{ runContext :: forall f. `Functor`

f => (a -> f b) -> f t }`exists s. (s, `

.`Lens`

s t a b)

A `Context`

is like a `Lens`

that has already been applied to a some structure.

Context (b -> t) a |

IndexedComonadStore Context | |

IndexedComonad Context | |

IndexedFunctor Context | |

Sellable (->) Context | |

(~) * a b => ComonadStore a (Context a b) | |

Functor (Context a b) | |

(~) * a b => Comonad (Context a b) |

locus :: IndexedComonadStore p => Lens (p a c s) (p b c s) a b Source

This `Lens`

lets you `view`

the current `pos`

of any indexed
store comonad and `seek`

to a new position. This reduces the API
for working these instances to a single `Lens`

.

`ipos`

w ≡ w`^.`

`locus`

`iseek`

s w ≡ w`&`

`locus`

`.~`

s`iseeks`

f w ≡ w`&`

`locus`

`%~`

f

`locus`

::`Lens'`

(`Context'`

a s) a`locus`

::`Conjoined`

p =>`Lens'`

(`Pretext'`

p a s) a`locus`

::`Conjoined`

p =>`Lens'`

(`PretextT'`

p g a s) a

# Lens fusion

fusing :: Functor f => LensLike (Yoneda f) s t a b -> LensLike f s t a b Source

Fuse a composition of lenses using `Yoneda`

to provide `fmap`

fusion.

In general, given a pair of lenses `foo`

and `bar`

fusing (foo.bar) = foo.bar

however, `foo`

and `bar`

are either going to `fmap`

internally or they are trivial.

`fusing`

exploits the `Yoneda`

lemma to merge these separate uses into a single `fmap`

.

This is particularly effective when the choice of functor `f`

is unknown at compile
time or when the `Lens`

`foo.bar`

in the above description is recursive or complex
enough to prevent inlining.

`fusing`

::`Lens`

s t a b ->`Lens`

s t a b