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`

=
`Mutator`

.

Every `Lens`

can be used for `Getting`

like a
`Fold`

that doesn't use the `Applicative`

or
`Gettable`

.

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

is a superclass of `Gettable`

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
- class Focus st where
- class (MonadState s m, MonadState t n) => Zoom m n s t | m -> s, n -> t, m t -> n, n s -> m where
- zoom :: SimpleLensLike (IndexedStore s s) t s -> m c -> n c

- class Field1 a b c d | a -> c, b -> d, a d -> b, b c -> a where
- class Field2 a b c d | a -> c, b -> d, a d -> b, b c -> a where
- class Field3 a b c d | a -> c, b -> d, a d -> b, b c -> a where
- class Field4 a b c d | a -> c, b -> d, a d -> b, b c -> a where
- class Field5 a b c d | a -> c, b -> d, a d -> b, b c -> a where
- class Field6 a b c d | a -> c, b -> d, a d -> b, b c -> a where
- class Field7 a b c d | a -> c, b -> d, a d -> b, b c -> a where
- class Field8 a b c d | a -> c, b -> d, a d -> b, b c -> a where
- class Field9 a b c d | a -> c, b -> d, a d -> b, b c -> a where
- resultAt :: Eq e => e -> Simple Lens (e -> a) a
- 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
- alongside :: Lens a b c d -> Lens a' b' c' d' -> Lens (a, a') (b, b') (c, c') (d, d')
- (<%~) :: LensLike ((,) d) a b c d -> (c -> d) -> a -> (d, b)
- (<+~) :: Num c => LensLike ((,) c) a b c c -> c -> a -> (c, b)
- (<-~) :: Num c => LensLike ((,) c) a b c c -> c -> a -> (c, b)
- (<*~) :: Num c => LensLike ((,) c) a b c c -> c -> a -> (c, b)
- (<//~) :: Fractional c => LensLike ((,) c) a b c c -> c -> a -> (c, b)
- (<^~) :: (Num c, Integral d) => LensLike ((,) c) a b c c -> d -> a -> (c, b)
- (<^^~) :: (Fractional c, Integral d) => LensLike ((,) c) a b c c -> d -> a -> (c, b)
- (<**~) :: Floating c => LensLike ((,) c) a b c c -> c -> a -> (c, b)
- (<||~) :: LensLike ((,) Bool) a b Bool Bool -> Bool -> a -> (Bool, b)
- (<&&~) :: LensLike ((,) Bool) a b Bool Bool -> Bool -> a -> (Bool, b)
- (<%=) :: MonadState a m => LensLike ((,) d) a a c d -> (c -> d) -> m d
- (<+=) :: (MonadState a m, Num b) => SimpleLensLike ((,) b) a b -> b -> m b
- (<-=) :: (MonadState a m, Num b) => SimpleLensLike ((,) b) a b -> b -> m b
- (<*=) :: (MonadState a m, Num b) => SimpleLensLike ((,) b) a b -> b -> m b
- (<//=) :: (MonadState a m, Fractional b) => SimpleLensLike ((,) b) a b -> b -> m b
- (<^=) :: (MonadState a m, Num b, Integral c) => SimpleLensLike ((,) b) a b -> c -> m b
- (<^^=) :: (MonadState a m, Fractional b, Integral c) => SimpleLensLike ((,) b) a b -> c -> m b
- (<**=) :: (MonadState a m, Floating b) => SimpleLensLike ((,) b) a b -> b -> m b
- (<||=) :: MonadState a m => SimpleLensLike ((,) Bool) a Bool -> Bool -> m Bool
- (<&&=) :: MonadState a m => SimpleLensLike ((,) Bool) a Bool -> Bool -> m Bool
- clone :: Functor f => LensLike (IndexedStore c d) a b c d -> (c -> f d) -> a -> f b
- 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`

a b c d = forall f.`Functor`

f =>`LensLike`

f a b c d

type Simple f a b = f a a b bSource

A `Simple`

`Lens`

, `Simple`

`Traversal`

, ... can
be used instead of a `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

# 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

class (MonadState s m, MonadState t n) => Zoom m n s t | m -> s, n -> t, m t -> n, n s -> m whereSource

This class allows us to use `zoom`

in, changing the State supplied by
many different monad transformers. Unlike `focus`

this can change the state
of a deeply nested monad transformer. However, also unlike `focus`

it can
only be used on an actual `Lens`

or `Iso`

and cannot accept
a `Traversal`

zoom :: SimpleLensLike (IndexedStore s s) t s -> m c -> n cSource

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

`Lens`

.

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

This can be used to edit pretty much any monad transformer stack with a state in it:

zoom ::`Monad`

m =>`Simple`

`Lens`

a b -> StateT b m c -> StateT a m c zoom ::`Monad`

m =>`Simple`

`Lens`

a b -> RWST r w b m c -> RWST r w a m c zoom ::`Monad`

m =>`Simple`

`Lens`

a b -> ErrorT e (RWST r w b m c) -> ErrorT e (RWST r w a m c) zoom ::`Monad`

m =>`Simple`

`Lens`

a b -> ErrorT e (RWST r w b m c) -> ErrorT e (RWST r w a m c) ...

Zoom m n s t => Zoom (ListT m) (ListT n) s t | |

Zoom m n s t => Zoom (MaybeT m) (MaybeT n) s t | |

Zoom m n s t => Zoom (IdentityT m) (IdentityT n) s t | |

Zoom m m a a => Zoom (ContT r m) (ContT r m) a a | |

(Error e, Zoom m n s t) => Zoom (ErrorT e m) (ErrorT e n) s t | |

Zoom m n s t => Zoom (ReaderT e m) (ReaderT e n) s t | |

Monad m => Zoom (StateT s m) (StateT t m) s t | |

Monad m => Zoom (StateT s m) (StateT t m) s t | |

(Monoid w, Zoom m n s t) => Zoom (WriterT w m) (WriterT w n) s t | |

(Monoid w, Zoom m n s t) => Zoom (WriterT w m) (WriterT w n) s t | |

(Monoid w, Monad m) => Zoom (RWST r w s m) (RWST r w t m) s t | |

(Monoid w, Monad m) => Zoom (RWST r w s m) (RWST r w t m) s t |

# Common Lenses

## Tuples

class Field1 a b c d | a -> c, b -> d, a d -> b, b c -> a whereSource

Provides access to 1st field of a tuple.

Access the 1st field of a tuple (and possibly change its type).

`>>>`

`import Control.Lens`

`>>>`

1`(1,2)^._1`

`>>>`

("hello",2)`_1 .~ "hello" $ (1,2)`

This can also be used on larger tuples as well

`>>>`

(42,2,3,4,5)`_1 +~ 41 $ (1,2,3,4,5)`

_1 ::`Lens`

(a,b) (a',b) a a' _1 ::`Lens`

(a,b,c) (a',b,c) a a' _1 ::`Lens`

(a,b,c,d) (a',b,c,d) a a' ... _1 ::`Lens`

(a,c,d,e,f,g,h,i) (a',b,c,d,e,f,g,h,i) a a'

Field1 (a, b) (a', b) a a' | |

Field1 (a, b, c) (a', b, c) a a' | |

Field1 (a, b, c, d) (a', b, c, d) a a' | |

Field1 (a, b, c, d, e) (a', b, c, d, e) a a' | |

Field1 (a, b, c, d, e, f) (a', b, c, d, e, f) a a' | |

Field1 (a, b, c, d, e, f, g) (a', b, c, d, e, f, g) a a' | |

Field1 (a, b, c, d, e, f, g, h) (a', b, c, d, e, f, g, h) a a' | |

Field1 (a, b, c, d, e, f, g, h, i) (a', b, c, d, e, f, g, h, i) a a' |

class Field2 a b c d | a -> c, b -> d, a d -> b, b c -> a whereSource

Provides access to the 2nd field of a tuple

Access the 2nd field of a tuple

`>>>`

`import Control.Lens`

`>>>`

(1,"hello",3,4)`_2 .~ "hello" $ (1,(),3,4)`

`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

Field2 (a, b) (a, b') b b' | |

Field2 (a, b, c) (a, b', c) b b' | |

Field2 (a, b, c, d) (a, b', c, d) b b' | |

Field2 (a, b, c, d, e) (a, b', c, d, e) b b' | |

Field2 (a, b, c, d, e, f) (a, b', c, d, e, f) b b' | |

Field2 (a, b, c, d, e, f, g) (a, b', c, d, e, f, g) b b' | |

Field2 (a, b, c, d, e, f, g, h) (a, b', c, d, e, f, g, h) b b' | |

Field2 (a, b, c, d, e, f, g, h, i) (a, b', c, d, e, f, g, h, i) b b' |

class Field3 a b c d | a -> c, b -> d, a d -> b, b c -> a whereSource

Provides access to the 3rd field of a tuple

Field3 (a, b, c) (a, b, c') c c' | |

Field3 (a, b, c, d) (a, b, c', d) c c' | |

Field3 (a, b, c, d, e) (a, b, c', d, e) c c' | |

Field3 (a, b, c, d, e, f) (a, b, c', d, e, f) c c' | |

Field3 (a, b, c, d, e, f, g) (a, b, c', d, e, f, g) c c' | |

Field3 (a, b, c, d, e, f, g, h) (a, b, c', d, e, f, g, h) c c' | |

Field3 (a, b, c, d, e, f, g, h, i) (a, b, c', d, e, f, g, h, i) c c' |

class Field4 a b c d | a -> c, b -> d, a d -> b, b c -> a whereSource

Provide access to the 4th field of a tuple

Field4 (a, b, c, d) (a, b, c, d') d d' | |

Field4 (a, b, c, d, e) (a, b, c, d', e) d d' | |

Field4 (a, b, c, d, e, f) (a, b, c, d', e, f) d d' | |

Field4 (a, b, c, d, e, f, g) (a, b, c, d', e, f, g) d d' | |

Field4 (a, b, c, d, e, f, g, h) (a, b, c, d', e, f, g, h) d d' | |

Field4 (a, b, c, d, e, f, g, h, i) (a, b, c, d', e, f, g, h, i) d d' |

class Field5 a b c d | a -> c, b -> d, a d -> b, b c -> a whereSource

Provides access to the 5th field of a tuple

class Field6 a b c d | a -> c, b -> d, a d -> b, b c -> a whereSource

Provides access to the 6th element of a tuple

class Field7 a b c d | a -> c, b -> d, a d -> b, b c -> a whereSource

Provide access to the 7th field of a tuple

class Field8 a b c d | a -> c, b -> d, a d -> b, b c -> a whereSource

Provide access to the 8th field of a tuple

class Field9 a b c d | a -> c, b -> d, a d -> b, b c -> a whereSource

Provides access to the 9th field of a tuple

Field9 (a, b, c, d, e, f, g, h, i) (a, b, c, d, e, f, g, h, i') i i' |

## Functions

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.

# Lateral Composition

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.

# Setting Functionally with Passthrough

(<//~) :: Fractional c => LensLike ((,) c) a b c c -> c -> a -> (c, b)Source

# Setting State with Passthrough

(<%=) :: MonadState a m => LensLike ((,) d) a a c d -> (c -> d) -> m dSource

(<+=) :: (MonadState a m, Num b) => SimpleLensLike ((,) b) a b -> b -> m bSource

(<-=) :: (MonadState a m, Num b) => SimpleLensLike ((,) b) a b -> b -> m bSource

(<*=) :: (MonadState a m, Num b) => SimpleLensLike ((,) b) a b -> b -> m bSource

(<//=) :: (MonadState a m, Fractional b) => SimpleLensLike ((,) b) a b -> b -> m bSource

(<^=) :: (MonadState a m, Num b, Integral c) => SimpleLensLike ((,) b) a b -> c -> m bSource

(<^^=) :: (MonadState a m, Fractional b, Integral c) => SimpleLensLike ((,) b) a b -> c -> m bSource

(<**=) :: (MonadState a m, Floating b) => SimpleLensLike ((,) b) a b -> b -> m bSource

(<||=) :: MonadState a m => SimpleLensLike ((,) Bool) a Bool -> Bool -> m BoolSource

(<&&=) :: MonadState a m => SimpleLensLike ((,) Bool) a Bool -> Bool -> m BoolSource

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

"Costate Comonad Coalgebra is equivalent of Java's member variable update technology for Haskell" -- @PLT_Borat on Twitter

# 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