lens-4.1.2.1: Lenses, Folds and Traversals

Copyright (C) 2012-14 Edward Kmett BSD-style (see the file LICENSE) Edward Kmett provisional non-portable Trustworthy Haskell98

Control.Lens.Prism

Description

Synopsis

# Prisms

type Prism s t a b = forall p f. (Choice p, Applicative f) => p a (f b) -> p s (f t) Source

A `Prism` `l` is a `Traversal` that can also be turned around with `re` to obtain a `Getter` in the opposite direction.

There are two laws that a `Prism` should satisfy:

First, if I `re` or `review` a value with a `Prism` and then `preview` or use ('Control.Lens.Fold.^?'), I will get it back:

````preview` l (`review` l b) ≡ `Just` b
```

Second, if you can extract a value `a` using a `Prism` `l` from a value `s`, then the value `s` is completely described my `l` and `a`:

If `preview l s ≡ Just a` then `review l a ≡ s`

These two laws imply that the `Traversal` laws hold for every `Prism` and that we `traverse` at most 1 element:

````lengthOf` l x `<=` 1
```

It may help to think of this as a `Iso` that can be partial in one direction.

Every `Prism` is a valid `Traversal`.

Every `Iso` is a valid `Prism`.

For example, you might have a `Prism' Integer Natural` allows you to always go from a `Natural` to an `Integer`, and provide you with tools to check if an `Integer` is a `Natural` and/or to edit one if it is.

````nat` :: `Prism'` `Integer` `Natural`
`nat` = `prism` `toInteger` `\$` \ i ->
if i `<` 0
then `Left` i
else `Right` (`fromInteger` i)
```

Now we can ask if an `Integer` is a `Natural`.

````>>> ````5^?nat
```Just 5
```
````>>> ````(-5)^?nat
```Nothing
```

We can update the ones that are:

````>>> ````(-3,4) & both.nat *~ 2
```(-3,8)
```

And we can then convert from a `Natural` to an `Integer`.

````>>> ````5 ^. re nat -- :: Natural
```5
```

Similarly we can use a `Prism` to `traverse` the `Left` half of an `Either`:

````>>> ````Left "hello" & _Left %~ length
```Left 5
```

or to construct an `Either`:

````>>> ````5^.re _Left
```Left 5
```

such that if you query it with the `Prism`, you will get your original input back.

````>>> ````5^.re _Left ^? _Left
```Just 5
```

Another interesting way to think of a `Prism` is as the categorical dual of a `Lens` -- a co-`Lens`, so to speak. This is what permits the construction of `outside`.

Note: Composition with a `Prism` is index-preserving.

type Prism' s a = Prism s s a a Source

A `Simple` `Prism`.

type APrism s t a b = Market a b a (Identity b) -> Market a b s (Identity t) Source

If you see this in a signature for a function, the function is expecting a `Prism`.

type APrism' s a = APrism s s a a Source

```type APrism' = `Simple` `APrism`
```

# Constructing Prisms

prism :: (b -> t) -> (s -> Either t a) -> Prism s t a b Source

Build a `Prism`.

`Either t a` is used instead of `Maybe a` to permit the types of `s` and `t` to differ.

prism' :: (b -> s) -> (s -> Maybe a) -> Prism s s a b Source

This is usually used to build a `Prism'`, when you have to use an operation like `cast` which already returns a `Maybe`.

# Consuming Prisms

clonePrism :: APrism s t a b -> Prism s t a b Source

Clone a `Prism` so that you can reuse the same monomorphically typed `Prism` for different purposes.

See `cloneLens` and `cloneTraversal` for examples of why you might want to do this.

outside :: Representable p => APrism s t a b -> Lens (p t r) (p s r) (p b r) (p a r) Source

Use a `Prism` as a kind of first-class pattern.

``outside` :: `Prism` s t a b -> `Lens` (t -> r) (s -> r) (b -> r) (a -> r)`

aside :: APrism s t a b -> Prism (e, s) (e, t) (e, a) (e, b) Source

Use a `Prism` to work over part of a structure.

without :: APrism s t a b -> APrism u v c d -> Prism (Either s u) (Either t v) (Either a c) (Either b d) Source

Given a pair of prisms, project sums.

Viewing a `Prism` as a co-`Lens`, this combinator can be seen to be dual to `alongside`.

below :: Traversable f => APrism' s a -> Prism' (f s) (f a) Source

`lift` a `Prism` through a `Traversable` functor, giving a Prism that matches only if all the elements of the container match the `Prism`.

isn't :: APrism s t a b -> s -> Bool Source

Check to see if this `Prism` doesn't match.

````>>> ````isn't _Left (Right 12)
```True
```
````>>> ````isn't _Left (Left 12)
```False
```
````>>> ````isn't _Empty []
```False
```

# Common Prisms

_Left :: Prism (Either a c) (Either b c) a b Source

This `Prism` provides a `Traversal` for tweaking the `Left` half of an `Either`:

````>>> ````over _Left (+1) (Left 2)
```Left 3
```
````>>> ````over _Left (+1) (Right 2)
```Right 2
```
````>>> ````Right 42 ^._Left :: String
```""
```
````>>> ````Left "hello" ^._Left
```"hello"
```

It also can be turned around to obtain the embedding into the `Left` half of an `Either`:

````>>> ````_Left # 5
```Left 5
```
````>>> ````5^.re _Left
```Left 5
```

_Right :: Prism (Either c a) (Either c b) a b Source

This `Prism` provides a `Traversal` for tweaking the `Right` half of an `Either`:

````>>> ````over _Right (+1) (Left 2)
```Left 2
```
````>>> ````over _Right (+1) (Right 2)
```Right 3
```
````>>> ````Right "hello" ^._Right
```"hello"
```
````>>> ````Left "hello" ^._Right :: [Double]
```[]
```

It also can be turned around to obtain the embedding into the `Right` half of an `Either`:

````>>> ````_Right # 5
```Right 5
```
````>>> ````5^.re _Right
```Right 5
```

_Just :: Prism (Maybe a) (Maybe b) a b Source

This `Prism` provides a `Traversal` for tweaking the target of the value of `Just` in a `Maybe`.

````>>> ````over _Just (+1) (Just 2)
```Just 3
```

Unlike `traverse` this is a `Prism`, and so you can use it to inject as well:

````>>> ````_Just # 5
```Just 5
```
````>>> ````5^.re _Just
```Just 5
```

Interestingly,

```m '^?' `_Just` ≡ m
```
````>>> ````Just x ^? _Just
```Just x
```
````>>> ````Nothing ^? _Just
```Nothing
```

_Nothing :: Prism' (Maybe a) () Source

This `Prism` provides the `Traversal` of a `Nothing` in a `Maybe`.

````>>> ````Nothing ^? _Nothing
```Just ()
```
````>>> ````Just () ^? _Nothing
```Nothing
```

But you can turn it around and use it to construct `Nothing` as well:

````>>> ````_Nothing # ()
```Nothing
```

_Void :: Prism s s a Void Source

`Void` is a logically uninhabited data type.

This is a `Prism` that will always fail to match.

_Show :: (Read a, Show a) => Prism' String a Source

This is an improper prism for text formatting based on `Read` and `Show`.

This `Prism` is "improper" in the sense that it normalizes the text formatting, but round tripping is idempotent given sane 'Read'/'Show' instances.

````>>> ````_Show # 2
```"2"
```
````>>> ````"EQ" ^? _Show :: Maybe Ordering
```Just EQ
```
````_Show` ≡ `prism'` `show` `readMaybe`
```

only :: Eq a => a -> Prism' a () Source

This `Prism` compares for exact equality with a given value.

````>>> ````only 4 # ()
```4
```
````>>> ````5 ^? only 4
```Nothing
```

nearly :: a -> (a -> Bool) -> Prism' a () Source

This `Prism` compares for approximate equality with a given value and a predicate for testing.

To comply with the `Prism` laws the arguments you supply to `nearly a p` are somewhat constrained.

We assume `p x` holds iff `x ≡ a`. Under that assumption then this is a valid `Prism`.

This is useful when working with a type where you can test equality for only a subset of its values, and the prism selects such a value.

# Prismatic profunctors

class Profunctor p => Choice p where

Minimal complete definition

Nothing

Methods

left' :: p a b -> p (Either a c) (Either b c)

right' :: p a b -> p (Either c a) (Either c b)

Instances

 Choice (->) Choice ReifiedFold Choice ReifiedGetter Monad m => Choice (Kleisli m) Comonad w => Choice (Cokleisli w) Choice (Tagged *) ArrowChoice p => Choice (WrappedArrow p) Applicative f => Choice (UpStar f) Monoid r => Choice (Forget r) Traversable w => Choice (DownStar w) Choice (Indexed i) Choice (Market a b)