lens-5.2.3: 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 | Trustworthy
Language | Haskell2010

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 :: Type -> Type -> Type) (f :: Type -> Type). (Choice p, Bifunctor p, Settable f) => Optic' p f t b
- type AReview t b = Optic' (Tagged :: Type -> Type -> Type) 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 (forall a. Functor (p a)) => Bifunctor (p :: Type -> Type -> Type) 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 :: Type -> Type -> Type)
- reviewing :: (Bifunctor p, Functor f) => Optic (Tagged :: Type -> Type -> Type) Identity s t a b -> Optic' p f t b

# Reviewing

type Review t b = forall (p :: Type -> Type -> Type) (f :: Type -> Type). (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 :: Type -> Type -> Type) 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 (forall a. Functor (p a)) => Bifunctor (p :: Type -> Type -> Type) where #

A bifunctor is a type constructor that takes two type arguments and is a functor in both arguments. That is, unlike with `Functor`, a type constructor such as `Either` does not need to be partially applied for a `Bifunctor` instance, and the methods in this class permit mapping functions over the `Left` value or the `Right` value, or both at the same time.

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`. A partially applied `Bifunctor` must be a `Functor` and the `second` method must agree with `fmap`. From this it follows that:

    second id = id

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.18.0.0 `Functor` is a superclass of 'Bifunctor.

Since: base-4.8.0.0

Minimal complete definition

bimap | first, second

Methods

bimap :: (a -> b) -> (c -> d) -> p a c -> p b d #

Map over both arguments at the same time.

    bimap f g ≡ first f . second g

#### Examples

Expand

    >>> bimap toUpper (+1) ('j', 3)
    ('J',4)

    >>> bimap toUpper (+1) (Left 'j')
    Left 'J'

    >>> bimap toUpper (+1) (Right 3)
    Right 4

#### Instances

Instances details

Bifunctor Either | Since: base-4.8.0.0
Instance details Defined in Data.Bifunctor 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 Arg | Since: base-4.9.0.0
Instance details Defined in Data.Semigroup 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 Either |
Instance details Defined in Data.Strict.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 These |
Instance details Defined in Data.Strict.These Methods bimap :: (a -> b) -> (c -> d) -> These a c -> These b d # first :: (a -> b) -> These a c -> These b c # second :: (b -> c) -> These a b -> These a c #
Bifunctor Pair |
Instance details Defined in Data.Strict.Tuple Methods bimap :: (a -> b) -> (c -> d) -> Pair a c -> Pair b d # first :: (a -> b) -> Pair a c -> Pair b c # second :: (b -> c) -> Pair a b -> Pair a c #
Bifunctor These |
Instance details Defined in Data.These Methods bimap :: (a -> b) -> (c -> d) -> These a c -> These b d # first :: (a -> b) -> These a c -> These b c # second :: (b -> c) -> These a b -> These a c #

Bifunctor (,)

Class laws for tuples hold only up to laziness. Both `first` `id` and `second` `id` are lazier than `id` (and `fmap` `id`):

    >>> first id (undefined :: (Int, Word)) `seq` ()
    ()
    >>> second id (undefined :: (Int, Word)) `seq` ()
    ()
    >>> id (undefined :: (Int, Word)) `seq` ()
    *** Exception: Prelude.undefined

Since: base-4.8.0.0

Instance details Defined in Data.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 (Const :: Type -> Type -> Type) | Since: base-4.8.0.0
Instance details Defined in Data.Bifunctor 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 #
Bifunctor bi => Bifunctor (Biap bi) |
Instance details Defined in Data.Bifunctor.Biap Methods bimap :: (a -> b) -> (c -> d) -> Biap bi a c -> Biap bi b d # first :: (a -> b) -> Biap bi a c -> Biap bi b c # second :: (b -> c) -> Biap bi a b -> Biap bi a c #
Functor f => Bifunctor (CofreeF f) |
Instance details Defined in Control.Comonad.Trans.Cofree 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) |
Instance details Defined in Control.Monad.Trans.Free 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 #
Functor f => Bifunctor (FreeF f) |
Instance details Defined in Control.Monad.Trans.Free.Ap 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 #
Functor f => Bifunctor (AlongsideLeft f) # |
Instance details Defined in Control.Lens.Internal.Getter 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 #
Functor f => Bifunctor (AlongsideRight f) # |
Instance details Defined in Control.Lens.Internal.Getter 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 #
Bifunctor (Tagged :: Type -> Type -> Type) |
Instance details Defined in Data.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 :: Type -> Type -> Type) |
Instance details Defined in Data.Functor.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 #
Bifunctor ((,,) x1) | Since: base-4.8.0.0
Instance details Defined in Data.Bifunctor 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 (K1 i :: Type -> Type -> Type) | Since: base-4.9.0.0
Instance details Defined in Data.Bifunctor 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 x2) | Since: base-4.8.0.0
Instance details Defined in Data.Bifunctor 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) #
Functor f => Bifunctor (Clown f :: Type -> Type -> Type) |
Instance details Defined in Data.Bifunctor.Clown 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 p => Bifunctor (Flip p) |
Instance details Defined in Data.Bifunctor.Flip 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 g => Bifunctor (Joker g :: Type -> Type -> Type) |
Instance details Defined in Data.Bifunctor.Joker 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 (WrappedBifunctor p) |
Instance details Defined in Data.Bifunctor.Wrapped 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 #
Bifunctor ((,,,,) x1 x2 x3) | Since: base-4.8.0.0
Instance details Defined in Data.Bifunctor 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 f, Bifunctor g) => Bifunctor (Product f g) |
Instance details Defined in Data.Bifunctor.Product 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) |
Instance details Defined in Data.Bifunctor.Sum 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) | Since: base-4.8.0.0
Instance details Defined in Data.Bifunctor 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) #
(Functor f, Bifunctor p) => Bifunctor (Tannen f p) |
Instance details Defined in Data.Bifunctor.Tannen 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 ((,,,,,,) x1 x2 x3 x4 x5) | Since: base-4.8.0.0
Instance details Defined in Data.Bifunctor 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) #
(Bifunctor p, Functor f, Functor g) => Bifunctor (Biff p f g) |
Instance details Defined in Data.Bifunctor.Biff 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 :: Type -> Type -> Type) #

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

#### Instances

Instances details

(Profunctor p, Bifunctor p) => Reviewable p # |
Instance details Defined in Control.Lens.Internal.Review

reviewing :: (Bifunctor p, Functor f) => Optic (Tagged :: Type -> Type -> Type) Identity s t a b -> Optic' p f t b #

Coerce a polymorphic `Prism` to a `Review`.

    reviewing :: Iso s t a b -> Review t b
    reviewing :: Prism s t a b -> Review t b