|Copyright||(C) 2012-14 Edward Kmett|
|License||BSD-style (see the file LICENSE)|
|Maintainer||Edward Kmett <email@example.com>|
- type Prism s t a b = forall p f. (Choice p, Applicative f) => p a (f b) -> p s (f t)
- type Prism' s a = Prism s s a a
- type APrism s t a b = Market a b a (Identity b) -> Market a b s (Identity t)
- type APrism' s a = APrism s s a a
- prism :: (b -> t) -> (s -> Either t a) -> Prism s t a b
- prism' :: (b -> s) -> (s -> Maybe a) -> Prism s s a b
- withPrism :: APrism s t a b -> ((b -> t) -> (s -> Either t a) -> r) -> r
- clonePrism :: APrism s t a b -> Prism s t a b
- outside :: Representable p => APrism s t a b -> Lens (p t r) (p s r) (p b r) (p a r)
- aside :: APrism s t a b -> Prism (e, s) (e, t) (e, a) (e, b)
- without :: APrism s t a b -> APrism u v c d -> Prism (Either s u) (Either t v) (Either a c) (Either b d)
- below :: Traversable f => APrism' s a -> Prism' (f s) (f a)
- isn't :: APrism s t a b -> s -> Bool
- matching :: APrism s t a b -> s -> Either t a
- _Left :: Prism (Either a c) (Either b c) a b
- _Right :: Prism (Either c a) (Either c b) a b
- _Just :: Prism (Maybe a) (Maybe b) a b
- _Nothing :: Prism' (Maybe a) ()
- _Void :: Prism s s a Void
- _Show :: (Read a, Show a) => Prism' String a
- only :: Eq a => a -> Prism' a ()
- nearly :: a -> (a -> Bool) -> Prism' a ()
- class Profunctor p => Choice p where
There are two laws that a
Prism should satisfy:
Second, if you can extract a value
a using a
l from a value
s, then the value
s is completely described by
It may help to think of this as a
Iso that can be partial in one direction.
$\ i -> if i
Now we can ask if an
Integer is a
We can update the ones that are:
(-3,4) & both.nat *~ 2(-3,8)
And we can then convert from a
Natural to an
5 ^. re nat -- :: Natural5
Left "hello" & _Left %~ lengthLeft 5
or to construct an
5^.re _LeftLeft 5
such that if you query it with the
Prism, you will get your original input back.
5^.re _Left ^? _LeftJust 5
Note: Composition with a
Prism is index-preserving.
If you see this in a signature for a function, the function is expecting a
APrism to the pair of functions that characterize it.
Prism to work over part of a structure.
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
Retrieve the value targeted by a
Prism or return the
original value while allowing the type to change if it does
matching _Just (Just 12)Right 12
matching _Just (Nothing :: Maybe Int) :: Either (Maybe Bool) IntLeft Nothing
over _Left (+1) (Left 2)Left 3
over _Left (+1) (Right 2)Right 2
Right 42 ^._Left :: String""
Left "hello" ^._Left"hello"
_Left # 5Left 5
5^.re _LeftLeft 5
over _Right (+1) (Left 2)Left 2
over _Right (+1) (Right 2)Right 3
Right "hello" ^._Right"hello"
Left "hello" ^._Right :: [Double]
_Right # 5Right 5
5^.re _RightRight 5
over _Just (+1) (Just 2)Just 3
_Just # 5Just 5
5^.re _JustJust 5
Just x ^? _JustJust x
Nothing ^? _JustNothing
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 OrderingJust EQ
Prism compares for exact equality with a given value.
only 4 # ()4
5 ^? only 4Nothing
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.
p x holds iff
x ≡ a. Under that assumption then this is a valid
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.
Note: This is also a notion of strength, except with regards to another monoidal structure that we can choose to equip Hask with: the cocartesian coproduct.
|Monad m => Choice (Kleisli m)|
|Comonad w => Choice (Cokleisli w)|
|Applicative f => Choice (UpStar f)|
|Traversable w => Choice (DownStar w)|
|ArrowChoice p => Choice (WrappedArrow p)|
|Monoid r => Choice (Forget r)|
|Choice (Tagged *)|
|Choice (Indexed i)|
|Choice (Market a b)|