lens-1.8: Lenses, Folds and Traversals

Portability Rank2Types provisional Edward Kmett Safe-Infered

Control.Lens.Getter

Description

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 `Accessor` to obtain

`type `Getting` r a c = (c -> `Accessor` r c) -> a -> `Accessor` r a`

If we restrict access to knowledge about the type `r` and can work for any d and b, we could get:

`type `Getter` a c = forall r. `Getting` r a c`

But we actually hide the use of `Accessor` behind a class `Gettable` to error messages from type class resolution rather than at unification time, where they are much uglier.

`type `Getter` a c = forall f. `Gettable` f => (c -> f c) -> a -> f a`

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.

Synopsis

# Getters

type Getter a c = forall f. Gettable f => (c -> f c) -> a -> f aSource

A `Getter` describes how to retrieve a single value in a way that can be composed with other lens-like constructions.

Unlike a `Lens` a `Getter` is read-only. Since a `Getter` cannot be used to write back there are no lens laws that can be applied to it. In fact, it is isomorphic to an arbitrary function from `(a -> c)`.

Moreover, a `Getter` can be used directly as a `Fold`, since it just ignores the `Applicative`.

type Getting r a c = (c -> Accessor r c) -> a -> Accessor r aSource

Most `Getter` combinators are able to be used with both a `Getter` or a `Fold` in limited situations, to do so, they need to be monomorphic in what we are going to extract with `Const`. To be compatible with `Lens`, `Traversal` and `Iso` we also restricted choices of the irrelevant b and d parameters.

If a function accepts a `Getting r a c`, then when `r` is a `Monoid`, then you can pass a `Fold` (or `Traversal`), otherwise you can only pass this a `Getter` or `Lens`.

class Functor f => Gettable f whereSource

Generalizing `Const` so we can apply simple `Applicative` transformations to it and so we can get nicer error messages

A `Gettable` `Functor` ignores its argument, which it carries solely as a phantom type parameter.

To ensure this, it is required to satisfy:

``` id = fmap f = coerce
```

Methods

coerce :: f a -> f bSource

Replace the phantom type argument.

Instances

 Gettable (Const r) Gettable f => Gettable (Backwards f) Gettable f => Gettable (ElementOf f) This instance is a lie, but it is a useful lie. Gettable (Accessor r) (Functor f, Gettable g) => Gettable (Compose f g) Monad m => Gettable (Effect m r)

newtype Accessor r a Source

Used instead of `Const` to report

`No instance of (`Settable` `Accessor`)`

when the user attempts to misuse a `Setter` as a `Getter`, rather than a monolithic unification error.

Constructors

 Accessor FieldsrunAccessor :: r

Instances

 Effective Identity r (Accessor r) Functor (Accessor r) Monoid r => Applicative (Accessor r) Gettable (Accessor r)

# Building Getters

to :: (a -> c) -> Getter a cSource

Build a `Getter` from an arbitrary Haskell function.

``to` f . `to` g = `to` (g . f)`
`a `^.` `to` f = f a`
````>>> ````import Control.Lens
````>>> ````(0, -5)^._2.to abs
```5
```

# Combinators for Getters and Folds

(^.) :: a -> Getting c a c -> cSource

View the value pointed to by a `Getter` or `Lens` or the result of folding over all the results of a `Fold` or `Traversal` that points at a monoidal values.

This is the same operation as `view` with the arguments flipped.

The fixity and semantics are such that subsequent field accesses can be performed with (`.`)

````>>> ````:m + Data.Complex Control.Lens
````>>> ````((0, 1 :+ 2), 3)^._1._2.to magnitude
```2.23606797749979
```
``` (^.) ::             a -> `Getter` a c          -> c
(^.) :: `Monoid` m => a -> `Fold` a m            -> m
(^.) ::             a -> `Simple` `Iso` a c         -> c
(^.) ::             a -> `Simple` `Lens` a c        -> c
(^.) :: `Monoid` m => a -> `Simple` `Traversal` a m   -> m
```

(^\$) :: Getting c a c -> a -> cSource

View the value pointed to by a `Getter`, `Iso` or `Lens` or the result of folding over all the results of a `Fold` or `Traversal` that points at a monoidal values.

This is the same operation as `view`, only infix.

````>>> ````import Control.Lens
````>>> ````_2 ^\$ (1, "hello")
```"hello"
```
``` (^\$) ::             `Getter` a c          -> a -> c
(^\$) :: `Monoid` m => `Fold` a m            -> a -> m
(^\$) ::             `Simple` `Iso` a c         -> a -> c
(^\$) ::             `Simple` `Lens` a c        -> a -> c
(^\$) :: `Monoid` m => `Simple` `Traversal` a m   -> a -> m
```

view :: Getting c a c -> a -> cSource

View the value pointed to by a `Getter`, `Iso` or `Lens` or the result of folding over all the results of a `Fold` or `Traversal` that points at a monoidal values.

It may be useful to think of `view` as having these more restrictive signatures:

``view` . `to` = `id``
````>>> ````import Control.Lens
````>>> ````view _2 (1,"hello")
```"hello"
```
``` view ::             `Getter` a c          -> a -> c
view :: `Monoid` m => `Fold` a m            -> a -> m
view ::             `Simple` `Iso` a c         -> a -> c
view ::             `Simple` `Lens` a c        -> a -> c
view :: `Monoid` m => `Simple` `Traversal` a m   -> a -> m
```

views :: Getting m a c -> (c -> m) -> a -> mSource

View the value of a `Getter`, `Iso`, `Lens` or the result of folding over the result of mapping the targets of a `Fold` or `Traversal`.

It may be useful to think of `views` as having these more restrictive signatures:

````>>> ````import Control.Lens
````>>> ````views _2 length (1,"hello")
```5
```
``` views ::             `Getter` a c          -> (c -> d) -> a -> d
views :: `Monoid` m => `Fold` a c            -> (c -> m) -> a -> m
views ::             `Simple` `Iso` a c         -> (c -> d) -> a -> d
views ::             `Simple` `Lens` a c        -> (c -> d) -> a -> d
views :: `Monoid` m => `Simple` `Traversal` a c   -> (c -> m) -> a -> m
```

use :: MonadState a m => Getting c a c -> m cSource

Use the target of a `Lens`, `Iso`, or `Getter` in the current state, or use a summary of a `Fold` or `Traversal` that points to a monoidal value.

``` use :: `MonadState` a m             => `Getter` a c          -> m c
use :: (`MonadState` a m, `Monoid` r) => `Fold` a r            -> m r
use :: `MonadState` a m             => `Simple` `Iso` a c         -> m c
use :: `MonadState` a m             => `Simple` `Lens` a c        -> m c
use :: (`MonadState` a m, `Monoid` r) => `Simple` `Traversal` a r   -> m r
```

uses :: MonadState a m => Getting e a c -> (c -> e) -> m eSource

Use the target of a `Lens`, `Iso` or `Getter` in the current state, or use a summary of a `Fold` or `Traversal` that points to a monoidal value.

``` uses :: `MonadState` a m             => `Getter` a c        -> (c -> e) -> m e
uses :: (`MonadState` a m, `Monoid` r) => `Fold` a c          -> (c -> r) -> m r
uses :: `MonadState` a m             => `Simple` `Lens` a c      -> (c -> e) -> m e
uses :: `MonadState` a m             => `Simple` `Iso` a c       -> (c -> e) -> m e
uses :: (`MonadState` a m, `Monoid` r) => `Simple` `Traversal` a c -> (c -> r) -> m r
```

query :: MonadReader a m => Getting c a c -> m cSource

Query the target of a `Lens`, `Iso` or `Getter` in the current state, or use a summary of a `Fold` or `Traversal` that points to a monoidal value.

``` query :: `MonadReader` a m             => `Getter` a c        -> m c
query :: (`MonadReader` a m, `Monoid` c) => `Fold` a c          -> m c
query :: `MonadReader` a m             => `Simple` `Iso` a c       -> m c
query :: `MonadReader` a m             => `Simple` `Lens` a c      -> m c
query :: (`MonadReader` a m, `Monoid` c) => `Simple` `Traversal` a c -> m c
```

queries :: MonadReader a m => Getting e a c -> (c -> e) -> m eSource

Use the target of a `Lens`, `Iso` or `Getter` in the current state, or use a summary of a `Fold` or `Traversal` that points to a monoidal value.

``` queries :: `MonadReader` a m             => `Getter` a c        -> (c -> e) -> m e
queries :: (`MonadReader` a m, `Monoid` c) => `Fold` a c          -> (c -> e) -> m e
queries :: `MonadReader` a m             => `Simple` `Iso` a c       -> (c -> e) -> m e
queries :: `MonadReader` a m             => `Simple` `Lens` a c      -> (c -> e) -> m e
queries :: (`MonadReader` a m, `Monoid` c) => `Simple` `Traversal` a c -> (c -> e) -> m e
```