Portability  nonportable 

Stability  provisional 
Maintainer  Edward Kmett <ekmett@gmail.com> 
Safe Haskell  Trustworthy 
 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 (Mutator b) > Market a b s (Mutator t)
 type APrism' s a = APrism s s a a
 prism :: (b > t) > (s > Either t a) > Prism s t a b
 prism' :: (a > s) > (s > Maybe a) > Prism' s a
 clonePrism :: APrism s t a b > Prism s t a b
 outside :: APrism 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)
 without :: APrism s t a b > APrism u v c d > Prism (Either s u) (Either t v) (Either a c) (Either b d)
 isn't :: APrism s t a b > s > Bool
 _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
 class Profunctor p => Choice p where
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 0or1 target 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 (^?
), 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
then preview
l s ≡ Just
areview
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
.
For example, you might have a
allows you to always
go from a Prism'
Integer
Natural
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 thenLeft
i elseRight
(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 coLens
, so to speak. This is what permits the construction of outside
.
Note: Composition with a Prism
is indexpreserving.
type APrism s t a b = Market a b a (Mutator b) > Market a b s (Mutator t)Source
If you see this in a signature for a function, the function is expecting a Prism
.
Constructing Prisms
Consuming Prisms
clonePrism :: APrism s t a b > Prism s t a bSource
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.
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
isn't :: APrism s t a b > s > BoolSource
Check to see if this Prism
doesn't match.
>>>
isn't _Left (Right 12)
True
>>>
isn't _Left (Left 12)
False
Common Prisms
_Left :: Prism (Either a c) (Either b c) a bSource
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
:
>>>
5^.re _Left
Left 5
_Right :: Prism (Either c a) (Either c b) a bSource
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
:
>>>
5^.re _Right
Right 5
Prismatic profunctors
class Profunctor p => Choice p where
The generalization of DownStar
of a "costrong" Functor
Minimal complete definition: left'
or right'
Note: We use traverse
and extract
as approximate costrength as needed.
Choice (>)  
Choice Reviewed  
(Profunctor (Kleisli m), Monad m) => Choice (Kleisli m)  
(Profunctor (Cokleisli w), Comonad w) => Choice (Cokleisli w) 

(Profunctor (DownStar w), Traversable w) => Choice (DownStar w) 

(Profunctor (WrappedArrow p), ArrowChoice p) => Choice (WrappedArrow p)  
Choice (Tagged *)  
Profunctor (Indexed i) => Choice (Indexed i)  
Profunctor (Market a b) => Choice (Market a b) 