Control.Lens.Review

lens-4.15.1: Lenses, Folds and Traversals

Copyright | (C) 2012-16 Edward Kmett
License | BSD-style (see the file LICENSE)
Maintainer | Edward Kmett <ekmett@gmail.com>
Stability | provisional
Portability | non-portable
Safe Haskell | None
Language | Haskell98

Control.Lens.Review

Contents

- Reviewing

Description

A `Review` is a type-restricted form of a `Prism` that can only be used for writing back via `re`, `review`, `reuse`.

Synopsis

- type Review t b = forall p f. (Choice p, Bifunctor p, Settable f) => Optic' p f t b
- type AReview t b = Optic' Tagged Identity t b
- unto :: (Profunctor p, Bifunctor p, Functor f) => (b -> t) -> Optic p f s t a b
- un :: (Profunctor p, Bifunctor p, Functor f) => Getting a s a -> Optic' p f a s
- re :: AReview t b -> Getter b t
- review :: MonadReader b m => AReview t b -> m t
- reviews :: MonadReader b m => AReview t b -> (t -> r) -> m r
- reuse :: MonadState b m => AReview t b -> m t
- reuses :: MonadState b m => AReview t b -> (t -> r) -> m r
- (#) :: AReview t b -> b -> t
- class Bifunctor p where
  - bimap :: (a -> b) -> (c -> d) -> p a c -> p b d
- retagged :: (Profunctor p, Bifunctor p) => p a b -> p s b
- class (Profunctor p, Bifunctor p) => Reviewable p

# Reviewing

type Review t b = forall p f. (Choice p, Bifunctor p, Settable f) => Optic' p f t b #

This is a limited form of a `Prism` that can only be used for `re` operations.

Like with a `Getter`, there are no laws to state for a `Review`.

You can generate a `Review` by using `unto`. You can also use any `Prism` or `Iso` directly as a `Review`.

type AReview t b = Optic' Tagged Identity t b #

If you see this in a signature for a function, the function is expecting a `Review` (in practice, this usually means a `Prism`).

unto :: (Profunctor p, Bifunctor p, Functor f) => (b -> t) -> Optic p f s t a b #

An analogue of `to` for `review`.

    unto :: (b -> t) -> Review' t b

    unto = un . to

un :: (Profunctor p, Bifunctor p, Functor f) => Getting a s a -> Optic' p f a s #

Turn a `Getter` around to get a `Review`

    un = unto . view
    unto = un . to

    >>> un (to length) # [1,2,3]
    3

re :: AReview t b -> Getter b t #

Turn a `Prism` or `Iso` around to build a `Getter`.

If you have an `Iso`, `from` is a more powerful version of this function that will return an `Iso` instead of a mere `Getter`.

    >>> 5 ^.re _Left
    Left 5

    >>> 6 ^.re (_Left.unto succ)
    Left 7

    review  ≡ view  . re
    reviews ≡ views . re
    reuse   ≡ use   . re
    reuses  ≡ uses  . re

    re :: Prism s t a b -> Getter b t
    re :: Iso s t a b   -> Getter b t

review :: MonadReader b m => AReview t b -> m t #

This can be used to turn an `Iso` or `Prism` around and `view` a value (or the current environment) through it the other way.

    review ≡ view . re
    review . unto ≡ id

    >>> review _Left "mustard"
    Left "mustard"

    >>> review (unto succ) 5
    6

Usually `review` is used in the `(->)` `Monad` with a `Prism` or `Iso`, in which case it may be useful to think of it as having one of these more restricted type signatures:

    review :: Iso' s a   -> a -> s
    review :: Prism' s a -> a -> s

However, when working with a `Monad` transformer stack, it is sometimes useful to be able to `review` the current environment, in which case it may be beneficial to think of it as having one of these slightly more liberal type signatures:

    review :: MonadReader a m => Iso' s a   -> m s
    review :: MonadReader a m => Prism' s a -> m s

reviews :: MonadReader b m => AReview t b -> (t -> r) -> m r #

This can be used to turn an `Iso` or `Prism` around and `view` a value (or the current environment) through it the other way, applying a function.

    reviews ≡ views . re
    reviews (unto f) g ≡ g . f

    >>> reviews _Left isRight "mustard"
    False

    >>> reviews (unto succ) (*2) 3
    8

Usually this function is used in the `(->)` `Monad` with a `Prism` or `Iso`, in which case it may be useful to think of it as having one of these more restricted type signatures:

    reviews :: Iso' s a   -> (s -> r) -> a -> r
    reviews :: Prism' s a -> (s -> r) -> a -> r

However, when working with a `Monad` transformer stack, it is sometimes useful to be able to `review` the current environment, in which case it may be beneficial to think of it as having one of these slightly more liberal type signatures:

    reviews :: MonadReader a m => Iso' s a   -> (s -> r) -> m r
    reviews :: MonadReader a m => Prism' s a -> (s -> r) -> m r

reuse :: MonadState b m => AReview t b -> m t #

This can be used to turn an `Iso` or `Prism` around and `use` a value (or the current environment) through it the other way.

    reuse ≡ use . re
    reuse . unto ≡ gets

    >>> evalState (reuse _Left) 5
    Left 5

    >>> evalState (reuse (unto succ)) 5
    6

    reuse :: MonadState a m => Prism' s a -> m s
    reuse :: MonadState a m => Iso' s a   -> m s

reuses :: MonadState b m => AReview t b -> (t -> r) -> m r #

This can be used to turn an `Iso` or `Prism` around and `use` the current state through it the other way, applying a function.

    reuses ≡ uses . re
    reuses (unto f) g ≡ gets (g . f)

    >>> evalState (reuses _Left isLeft) (5 :: Int)
    True

    reuses :: MonadState a m => Prism' s a -> (s -> r) -> m r
    reuses :: MonadState a m => Iso' s a   -> (s -> r) -> m r

(#) :: AReview t b -> b -> t infixr 8 #

An infix alias for `review`.

    unto f # x ≡ f x
    l # x ≡ x ^. re l

This is commonly used when using a `Prism` as a smart constructor.

    >>> _Left # 4
    Left 4

But it can be used for any `Prism`

    >>> base 16 # 123
    "7b"

    (#) :: Iso'      s a -> a -> s
    (#) :: Prism'    s a -> a -> s
    (#) :: Review    s a -> a -> s
    (#) :: Equality' s a -> a -> s

class Bifunctor p where #

Formally, the class `Bifunctor` represents a bifunctor from `Hask` -> `Hask`.

Intuitively it is a bifunctor where both the first and second arguments are covariant.

You can define a `Bifunctor` by either defining `bimap` or by defining both `first` and `second`.

If you supply `bimap`, you should ensure that:

    bimap id id ≡ id

If you supply `first` and `second`, ensure:

    first id ≡ id
    second id ≡ id

If you supply both, you should also ensure:

    bimap f g ≡ first f . second g

These ensure by parametricity:

    bimap  (f . g) (h . i) ≡ bimap f h . bimap g i
    first  (f . g) ≡ first  f . first  g
    second (f . g) ≡ second f . second g

Since: 4.8.0.0

Minimal complete definition

bimap | first, second

Instances

Bifunctor Either |
Methods bimap :: (a -> b) -> (c -> d) -> Either a c -> Either b d # first :: (a -> b) -> Either a c -> Either b c # second :: (b -> c) -> Either a b -> Either a c #
Bifunctor (,) |
Methods bimap :: (a -> b) -> (c -> d) -> (a, c) -> (b, d) # first :: (a -> b) -> (a, c) -> (b, c) # second :: (b -> c) -> (a, b) -> (a, c) #
Bifunctor Arg |
Methods bimap :: (a -> b) -> (c -> d) -> Arg a c -> Arg b d # first :: (a -> b) -> Arg a c -> Arg b c # second :: (b -> c) -> Arg a b -> Arg a c #
Bifunctor (K1 i) |
Methods bimap :: (a -> b) -> (c -> d) -> K1 i a c -> K1 i b d # first :: (a -> b) -> K1 i a c -> K1 i b c # second :: (b -> c) -> K1 i a b -> K1 i a c #
Bifunctor ((,,) x1) |
Methods bimap :: (a -> b) -> (c -> d) -> (x1, a, c) -> (x1, b, d) # first :: (a -> b) -> (x1, a, c) -> (x1, b, c) # second :: (b -> c) -> (x1, a, b) -> (x1, a, c) #
Bifunctor (Const *) |
Methods bimap :: (a -> b) -> (c -> d) -> Const * a c -> Const * b d # first :: (a -> b) -> Const * a c -> Const * b c # second :: (b -> c) -> Const * a b -> Const * a c #
Functor f => Bifunctor (CofreeF f) |
Methods bimap :: (a -> b) -> (c -> d) -> CofreeF f a c -> CofreeF f b d # first :: (a -> b) -> CofreeF f a c -> CofreeF f b c # second :: (b -> c) -> CofreeF f a b -> CofreeF f a c #
Functor f => Bifunctor (FreeF f) |
Methods bimap :: (a -> b) -> (c -> d) -> FreeF f a c -> FreeF f b d # first :: (a -> b) -> FreeF f a c -> FreeF f b c # second :: (b -> c) -> FreeF f a b -> FreeF f a c #
Bifunctor (Tagged *) |
Methods bimap :: (a -> b) -> (c -> d) -> Tagged * a c -> Tagged * b d # first :: (a -> b) -> Tagged * a c -> Tagged * b c # second :: (b -> c) -> Tagged * a b -> Tagged * a c #
Bifunctor (Constant *) |
Methods bimap :: (a -> b) -> (c -> d) -> Constant * a c -> Constant * b d # first :: (a -> b) -> Constant * a c -> Constant * b c # second :: (b -> c) -> Constant * a b -> Constant * a c #
Functor f => Bifunctor (AlongsideRight f) # |
Methods bimap :: (a -> b) -> (c -> d) -> AlongsideRight f a c -> AlongsideRight f b d # first :: (a -> b) -> AlongsideRight f a c -> AlongsideRight f b c # second :: (b -> c) -> AlongsideRight f a b -> AlongsideRight f a c #
Functor f => Bifunctor (AlongsideLeft f) # |
Methods bimap :: (a -> b) -> (c -> d) -> AlongsideLeft f a c -> AlongsideLeft f b d # first :: (a -> b) -> AlongsideLeft f a c -> AlongsideLeft f b c # second :: (b -> c) -> AlongsideLeft f a b -> AlongsideLeft f a c #
Bifunctor ((,,,) x1 x2) |
Methods bimap :: (a -> b) -> (c -> d) -> (x1, x2, a, c) -> (x1, x2, b, d) # first :: (a -> b) -> (x1, x2, a, c) -> (x1, x2, b, c) # second :: (b -> c) -> (x1, x2, a, b) -> (x1, x2, a, c) #
Bifunctor ((,,,,) x1 x2 x3) |
Methods bimap :: (a -> b) -> (c -> d) -> (x1, x2, x3, a, c) -> (x1, x2, x3, b, d) # first :: (a -> b) -> (x1, x2, x3, a, c) -> (x1, x2, x3, b, c) # second :: (b -> c) -> (x1, x2, x3, a, b) -> (x1, x2, x3, a, c) #
Bifunctor p => Bifunctor (WrappedBifunctor * * p) |
Methods bimap :: (a -> b) -> (c -> d) -> WrappedBifunctor * * p a c -> WrappedBifunctor * * p b d # first :: (a -> b) -> WrappedBifunctor * * p a c -> WrappedBifunctor * * p b c # second :: (b -> c) -> WrappedBifunctor * * p a b -> WrappedBifunctor * * p a c #
Functor g => Bifunctor (Joker * * g) |
Methods bimap :: (a -> b) -> (c -> d) -> Joker * * g a c -> Joker * * g b d # first :: (a -> b) -> Joker * * g a c -> Joker * * g b c # second :: (b -> c) -> Joker * * g a b -> Joker * * g a c #
Bifunctor p => Bifunctor (Flip * * p) |
Methods bimap :: (a -> b) -> (c -> d) -> Flip * * p a c -> Flip * * p b d # first :: (a -> b) -> Flip * * p a c -> Flip * * p b c # second :: (b -> c) -> Flip * * p a b -> Flip * * p a c #
Functor f => Bifunctor (Clown * * f) |
Methods bimap :: (a -> b) -> (c -> d) -> Clown * * f a c -> Clown * * f b d # first :: (a -> b) -> Clown * * f a c -> Clown * * f b c # second :: (b -> c) -> Clown * * f a b -> Clown * * f a c #
Bifunctor ((,,,,,) x1 x2 x3 x4) |
Methods bimap :: (a -> b) -> (c -> d) -> (x1, x2, x3, x4, a, c) -> (x1, x2, x3, x4, b, d) # first :: (a -> b) -> (x1, x2, x3, x4, a, c) -> (x1, x2, x3, x4, b, c) # second :: (b -> c) -> (x1, x2, x3, x4, a, b) -> (x1, x2, x3, x4, a, c) #
(Bifunctor f, Bifunctor g) => Bifunctor (Product * * f g) |
Methods bimap :: (a -> b) -> (c -> d) -> Product * * f g a c -> Product * * f g b d # first :: (a -> b) -> Product * * f g a c -> Product * * f g b c # second :: (b -> c) -> Product * * f g a b -> Product * * f g a c #
(Bifunctor p, Bifunctor q) => Bifunctor (Sum * * p q) |
Methods bimap :: (a -> b) -> (c -> d) -> Sum * * p q a c -> Sum * * p q b d # first :: (a -> b) -> Sum * * p q a c -> Sum * * p q b c # second :: (b -> c) -> Sum * * p q a b -> Sum * * p q a c #
Bifunctor ((,,,,,,) x1 x2 x3 x4 x5) |
Methods bimap :: (a -> b) -> (c -> d) -> (x1, x2, x3, x4, x5, a, c) -> (x1, x2, x3, x4, x5, b, d) # first :: (a -> b) -> (x1, x2, x3, x4, x5, a, c) -> (x1, x2, x3, x4, x5, b, c) # second :: (b -> c) -> (x1, x2, x3, x4, x5, a, b) -> (x1, x2, x3, x4, x5, a, c) #
(Functor f, Bifunctor p) => Bifunctor (Tannen * * * f p) |
Methods bimap :: (a -> b) -> (c -> d) -> Tannen * * * f p a c -> Tannen * * * f p b d # first :: (a -> b) -> Tannen * * * f p a c -> Tannen * * * f p b c # second :: (b -> c) -> Tannen * * * f p a b -> Tannen * * * f p a c #
(Bifunctor p, Functor f, Functor g) => Bifunctor (Biff * * * * p f g) |
Methods bimap :: (a -> b) -> (c -> d) -> Biff * * * * p f g a c -> Biff * * * * p f g b d # first :: (a -> b) -> Biff * * * * p f g a c -> Biff * * * * p f g b c # second :: (b -> c) -> Biff * * * * p f g a b -> Biff * * * * p f g a c #

retagged :: (Profunctor p, Bifunctor p) => p a b -> p s b #

This is a profunctor used internally to implement Review

It plays a role similar to that of `Accessor` or `Const` do for Control.Lens.Getter

class (Profunctor p, Bifunctor p) => Reviewable p #

This class is provided mostly for backwards compatibility with lens 3.8, but it can also shorten type signatures.

Instances

(Profunctor p, Bifunctor p) => Reviewable p # |