Safe Haskell | Safe |
---|---|
Language | Haskell2010 |
Synopsis
- 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
- prism :: (b -> t) -> (s -> Either t a) -> Prism s t a b
- prism' :: (b -> s) -> (s -> Maybe a) -> Prism s s a b
- is :: APrism s t a b -> s -> Bool
- only :: Eq a => a -> Prism' a ()
Prism
type Prism s t a b = forall (p :: * -> * -> *) (f :: * -> *). (Choice p, Applicative f) => p a (f b) -> p s (f t) #
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 (^?
), 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 by 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 co-Lens
, so to speak. This is what permits the construction of outside
.
Note: Composition with a Prism
is index-preserving.