1- -- | This module defines functions for working with prisms.
1+ -- | Prisms are used for selecting cases of a type, most often a sum
2+ -- | type. Consider this:
3+ -- |
4+ -- | ```purescript
5+ -- | data Fill -- think of a paint program filling a shape
6+ -- | = Solid Color
7+ -- | ...
8+ -- | ```
9+ -- |
10+ -- | A prism that focuses on `Solid` fills would be written like this:
11+ -- |
12+ -- | ```purescript
13+ -- | solidFocus :: Prism' Fill Color
14+ -- | solidFocus = prism' Solid case _ of
15+ -- | Solid color -> Just color
16+ -- | _ -> Nothing
17+ -- | ```
18+ -- |
19+ -- | ... and used like this:
20+ -- |
21+ -- | ```purescript
22+ -- | preview solidFocus (Solid Color.white) == Just Color.white
23+ -- | preview solidFocus NoFill == Nothing
24+ -- |
25+ -- | is solidFocus (Solid Color.white) == true
26+ -- | ```
27+ -- |
28+ -- | `review` can be used to go from a `Color` to a `Fill`:
29+ -- |
30+ -- | ```purescript
31+ -- | review solidFocus Color.white == Solid Color.white
32+ -- | ```
33+ -- |
34+ -- | For more information, see `PrismsForSumTypes` in the
35+ -- | `examples/src` directory.
36+
237module Data.Lens.Prism
3- ( prism , prism' , review , nearly , only , clonePrism , withPrism , matching
38+ ( prism , prism'
39+ , only , nearly
40+ , review
441 , is , isn't
42+ , clonePrism , withPrism , matching
543 , module ExportTypes
644 ) where
745
@@ -18,23 +56,79 @@ import Data.Profunctor (dimap, rmap)
1856import Data.Profunctor.Choice (right )
1957import Data.Newtype (under )
2058
21- -- | Create a `Prism` from a constructor/pattern pair.
59+ -- | Create a `Prism` from a constructor and a "focus" function that
60+ -- | produces an `Either`:
61+ -- |
62+ -- | ```purescript
63+ -- | solidFocus' :: Prism' Fill Color
64+ -- | solidFocus' = prism Solid case _ of
65+ -- | Solid color -> Right color
66+ -- | anotherCase -> Left anotherCase
67+ -- | ```
2268prism :: forall s t a b . (b -> t ) -> (s -> Either t a ) -> Prism s t a b
2369prism to fro pab = dimap fro (either id id) (right (rmap to pab))
2470
71+ -- | Create a `Prism` from a constructor and a "focus" function that
72+ -- | produces an `Maybe`:
73+ -- |
74+ -- | ```purescript
75+ -- | solidFocus' :: Prism' Fill Color
76+ -- | solidFocus' = prism' Solid case _ of
77+ -- | Solid color -> Just color
78+ -- | _ -> Nothing
79+ -- | ```
2580prism' :: forall s a . (a -> s ) -> (s -> Maybe a ) -> Prism' s a
2681prism' to fro = prism to (\s -> maybe (Left s) Right (fro s))
2782
28- -- | Review a value through a `Prism`.
29- review :: forall s t a b . Review s t a b -> b -> t
30- review = under Tagged
83+ -- | Create a prism that focuses on only some of the values of a case,
84+ -- | such as solid colors that are "bright enough":
85+ -- |
86+ -- | ```purescript
87+ -- | brightSolidFocus :: Prism' Fill Unit
88+ -- | brightSolidFocus = nearly (Solid referenceColor) predicate
89+ -- | where
90+ -- | referenceColor = Color.graytone 0.8
91+ -- | predicate = case _ of
92+ -- | Solid color ->
93+ -- | Color.brightness color >= Color.brightness referenceColor
94+ -- | _ ->
95+ -- | false
96+ -- |
97+ -- | preview brightSolidFocus (Solid Color.white) == Just unit
98+ -- | preview brightSolidFocus (Solid Color.black) == Nothing
99+ -- | preview brightSolidFocus NoFill == Nothing
100+ -- |
101+ -- | is brightSolidFocus (Solid Color.white) == true
102+ -- | review brightSolidFocus unit == Color.graytone 0.8
103+ -- | ```
104+
31105
32106nearly :: forall a . a -> (a -> Boolean ) -> Prism' a Unit
33107nearly x f = prism' (const x) (guard <<< f)
34108
109+ -- | `only` focuses not just on a case, but a specific value of that case.
110+ -- |
111+ -- | ```purescript
112+ -- | solidWhiteFocus :: Prism' Fill Unit
113+ -- | solidWhiteFocus = only $ Solid Color.white
114+ -- |
115+ -- | is solidWhiteFocus (Solid Color.white) == true
116+ -- | preview solidWhiteFocus (Solid Color.white) == Just unit
117+ -- | review solidWhiteFocus unit == Solid Color.white
118+ -- | ```
35119only :: forall a . Eq a => a -> Prism a a Unit Unit
36120only x = nearly x (_ == x)
37121
122+
123+ -- | Create the "whole" corresponding to a specific "part":
124+ -- |
125+ -- | ```purescript
126+ -- | -- solidFocus is a `Prism Fill Color`
127+ -- | review solidFocus Color.white == Solid Color.white
128+ -- | ```
129+ review :: forall s t a b . Review s t a b -> b -> t
130+ review = under Tagged
131+
38132clonePrism :: forall s t a b . APrism s t a b -> Prism s t a b
39133clonePrism l = withPrism l \x y p -> prism x y p
40134
@@ -45,8 +139,10 @@ withPrism l f = case l (Market id Right) of
45139matching :: forall s t a b . APrism s t a b -> s -> Either t a
46140matching l = withPrism l \_ f -> f
47141
142+ -- | Would `preview prism` produce a `Just`?
48143is :: forall s t a b r . HeytingAlgebra r => APrism s t a b -> s -> r
49144is l = either (const ff) (const tt) <<< matching l
50145
146+ -- | Would `preview prism` produce a `Nothing`?
51147isn't :: forall s t a b r . HeytingAlgebra r => APrism s t a b -> s -> r
52148isn't l = not <<< is l
0 commit comments