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
+
2
37
module Data.Lens.Prism
3
- ( prism , prism' , review , nearly , only , clonePrism , withPrism , matching
38
+ ( prism , prism'
39
+ , only , nearly
40
+ , review
4
41
, is , isn't
42
+ , clonePrism , withPrism , matching
5
43
, module ExportTypes
6
44
) where
7
45
@@ -18,23 +56,79 @@ import Data.Profunctor (dimap, rmap)
18
56
import Data.Profunctor.Choice (right )
19
57
import Data.Newtype (under )
20
58
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
+ -- | ```
22
68
prism :: forall s t a b . (b -> t ) -> (s -> Either t a ) -> Prism s t a b
23
69
prism to fro pab = dimap fro (either id id) (right (rmap to pab))
24
70
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
+ -- | ```
25
80
prism' :: forall s a . (a -> s ) -> (s -> Maybe a ) -> Prism' s a
26
81
prism' to fro = prism to (\s -> maybe (Left s) Right (fro s))
27
82
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
+
31
105
32
106
nearly :: forall a . a -> (a -> Boolean ) -> Prism' a Unit
33
107
nearly x f = prism' (const x) (guard <<< f)
34
108
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
+ -- | ```
35
119
only :: forall a . Eq a => a -> Prism a a Unit Unit
36
120
only x = nearly x (_ == x)
37
121
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
+
38
132
clonePrism :: forall s t a b . APrism s t a b -> Prism s t a b
39
133
clonePrism l = withPrism l \x y p -> prism x y p
40
134
@@ -45,8 +139,10 @@ withPrism l f = case l (Market id Right) of
45
139
matching :: forall s t a b . APrism s t a b -> s -> Either t a
46
140
matching l = withPrism l \_ f -> f
47
141
142
+ -- | Would `preview prism` produce a `Just`?
48
143
is :: forall s t a b r . HeytingAlgebra r => APrism s t a b -> s -> r
49
144
is l = either (const ff) (const tt) <<< matching l
50
145
146
+ -- | Would `preview prism` produce a `Nothing`?
51
147
isn't :: forall s t a b r . HeytingAlgebra r => APrism s t a b -> s -> r
52
148
isn't l = not <<< is l
0 commit comments