Safe Haskell | None |
---|

- newtype Lens w m a b = Lens {
- runLens :: a -> m (b -> w a, b)

- type :-> = LensM Identity
- lens :: (a -> b) -> (a -> b -> a) -> a :-> b
- get :: Lens w Identity a b -> a -> b
- set :: (a :-> b) -> a -> b -> a
- modify :: (a :-> b) -> (b -> b) -> a -> a
- type :~> = LensM Maybe
- class Monad m => Lenses l m where
- type LensM = Lens Identity
- lensM :: Monad m => (a -> m b) -> (a -> m (b -> a)) -> LensM m a b
- lensMW :: Monad m => (a -> m b) -> (a -> m (b -> w a)) -> Lens w m a b
- newtype LensLift w m a b = LLift (Lens w m a b)
- newtype LensJoin m a b = LJoin (Lens m m a b)
- newtype LensW w a b = LW (Lens w Identity a b)
- fstL :: (Monad m, Monad w) => Lens w m (a, b) a
- sndL :: (Monad m, Monad w) => Lens w m (a, b) b
- eitherL :: (Monad m, Monad w) => Lens w m (Either a a) a
- (|||) :: (Monad m, Monad w) => Lens w m a c -> Lens w m b c -> Lens w m (Either a b) c
- factorL :: (Monad m, Monad w) => Lens w m (Either (a, b) (a, c)) (a, Either b c)
- distributeL :: (Monad m, Monad w) => Lens w m (a, Either b c) (Either (a, b) (a, c))
- isoL :: (Monad m, Monad w) => Iso m w a b -> Lens m w a b
- residualL :: (Monad m, Monad w) => Iso m w a (b, r) -> Lens m w a b
- (^$) :: Lens w Identity a b -> a -> b
- (^>>=) :: Lenses l m => m a -> l m a b -> m b

# Documentation

The Lenses here are parameterized over two Monads (by convention `m`

and
`w`

), so that the "extract" and "rebuild" phases of a lens set operation
each happen within their own environment.

Concretely, a lens like (`:->`

) with both environments set to the trivial
`Identity`

Monad, gives us the usual pure lens, whereas something like
(`:~>`

), where the `m`

environment is `Maybe`

gives one possibility for a
partial lens. These would be suitable for multi-constructor data types.

One might also like to use a lens as an interface to a type, capable of performing
validation (beyond the capabilities of the typechecker). In that case the
`w`

environment becomes useful, and you might have ```
:: Lens Maybe Identity
PhoneNumber [Int]
```

.

See "Monadic API" below for a concrete example.

Monad m => Functor m (Lens m m) (Lens Identity Identity) | |

(Monad w, Monad m) => PFunctor (,) (Lens w m) (Lens w m) | |

(Monad w, Monad m) => QFunctor (,) (Lens w m) (Lens w m) | |

(Monad w, Monad m) => Bifunctor (,) (Lens w m) (Lens w m) (Lens w m) | |

Monad m => Lenses (Lens Identity) m | |

(Monad w, Monad m) => Category (Lens w m) | |

(Monad w, Monad m) => HasTerminalObject (Lens w m) | |

(Monad w, Monad m) => Braided (Lens w m) (,) | |

(Monad w, Monad m) => Symmetric (Lens w m) (,) | |

(Monad w, Monad m) => Monoidal (Lens w m) (,) | |

(Monad w, Monad m) => Associative (Lens w m) (,) |

# Simple API

## Pure lenses

lens :: (a -> b) -> (a -> b -> a) -> a :-> bSource

Create a pure Lens from a getter and setter

lens g = lensM (fmap return g) . fmap (fmap return)

get :: Lens w Identity a b -> a -> bSource

Run the getter function of a pure lens

get l = runIdentity . getM l

set :: (a :-> b) -> a -> b -> aSource

Run the getter function of a pure lens

set l b = runIdentity . setM l a

## Partial lenses

# Monadic API

In addition to defining lenses that can fail and perform validation, we have the ability to construct more abstract and expressive Lenses. Here is an example of a lens on the "N-th" element of a list, that returns its results in the [] monad:

nth :: LensM [] [a] a nth = Lens $ foldr build [] where build n l = (return . (: map snd l), n) : map (prepend n) l prepend = first . fmap . liftM . (:)

We can compose this with other lenses like the lens on the `snd`

of a
tuple, just as we would like:

`>>>`

[[('a',0),('b',2),('c',3)],[('a',1),('b',0),('c',3)],[('a',1),('b',2),('c',0)]]`setM (sndL . nth) 0 [('a',1),('b',2),('c',3)]`

type LensM = Lens IdentitySource

A lens in which the setter returns its result in the trivial `Identity`

monad. This is appropriate e.g. for traditional partial lenses on sum types,
where there is a potential that the lens could fail only on the *outer*
constructor.

lensM :: Monad m => (a -> m b) -> (a -> m (b -> a)) -> LensM m a bSource

Create a monadic lens from a getter and setter

## Monadic variants

The setter continuation is embedded in the getter's Monadic
environment, so we offer several ways of combining different types of
getter environments (`m`

) and setter environments (`w`

), for Lenses
with complex effects.

Newtype wrappers around `Lens`

let us use the same `Lenses`

interface
for getting and setting for these various monad-combining schemes.

lensMW :: Monad m => (a -> m b) -> (a -> m (b -> w a)) -> Lens w m a bSource

Create a monadic Lens from a setter and getter.

lensMW g s = Lens $ \a-> liftM2 (,) (s a) (g a)

lenses in which `m`

== `w`

and we would like to `join`

the two in get/set

lenses in which only the setter `w`

is monadic

# Composing Lenses

In addition to the usual `Category`

instance, we define instances for
`Lens`

for a number of category-level abstractions from the categories
package. Here are the various combinators and pre-defined lenses from these
classes, with types shown for a simplified `Lens`

type.

import Control.Categorical.Bifunctor first :: Lens a b -> Lens (a,x) (b,x) second :: Lens a b -> Lens (x,a) (x,b) bimap :: Lens a b -> Lens x y -> Lens (a,x) (b,y)

import Control.Categorical.Object terminate :: Lens a ()

import Control.Category.Associative associate :: Lens ((a,b),c) (a,(b,c)) disassociate :: Lens (a,(b,c)) ((a,b),c)

import Control.Category.Braided braid :: Lens (a,b) (b,a)

import Control.Category.Monoidal idl :: Lens ((), a) a idr :: Lens (a,()) a coidl :: Lens a ((),a) coidr :: Lens a (a,())

import qualified Control.Categorical.Functor as C C.fmap :: (Monad m)=> Lens m m a b -> (m a :-> m b)

In addition the following combinators and pre-defined lenses are provided.

eitherL :: (Monad m, Monad w) => Lens w m (Either a a) aSource

codiag from Cartesian

eitherL = id ||| id

## Lenses from Isomorphisms

isoL :: (Monad m, Monad w) => Iso m w a b -> Lens m w a bSource

Convert an isomorphism `i`

to a `Lens`

. When ```
apply i . unapply i =
unapply i . apply i = id
```

, the resulting lens will be well-behaved.

residualL :: (Monad m, Monad w) => Iso m w a (b, r) -> Lens m w a bSource

Convert to a Lens an isomorphism between a value `a`

and a tuple of a
value `b`

with some "residual" value `r`

.

# Convenience operators

The little "^" hats are actually superscript "L"s (for Lens) that have fallen over.