7
7
import com .jnape .palatable .lambda .adt .hlist .Tuple2 ;
8
8
import com .jnape .palatable .lambda .functions .Fn1 ;
9
9
import com .jnape .palatable .lambda .functions .specialized .Pure ;
10
+ import com .jnape .palatable .lambda .functor .Applicative ;
10
11
import com .jnape .palatable .lambda .functor .Cocartesian ;
11
12
import com .jnape .palatable .lambda .functor .Functor ;
12
13
import com .jnape .palatable .lambda .functor .Profunctor ;
13
14
import com .jnape .palatable .lambda .functor .builtin .Identity ;
15
+ import com .jnape .palatable .lambda .functor .builtin .Lazy ;
14
16
import com .jnape .palatable .lambda .functor .builtin .Market ;
17
+ import com .jnape .palatable .lambda .monad .Monad ;
15
18
import com .jnape .palatable .lambda .optics .functions .Matching ;
16
19
import com .jnape .palatable .lambda .optics .functions .Pre ;
17
20
import com .jnape .palatable .lambda .optics .functions .Re ;
18
21
import com .jnape .palatable .lambda .optics .functions .View ;
19
22
23
+ import static com .jnape .palatable .lambda .adt .Either .left ;
24
+ import static com .jnape .palatable .lambda .functions .builtin .fn1 .Constantly .constantly ;
25
+ import static com .jnape .palatable .lambda .functions .builtin .fn1 .Downcast .downcast ;
26
+ import static com .jnape .palatable .lambda .functions .builtin .fn1 .Upcast .upcast ;
27
+ import static com .jnape .palatable .lambda .optics .Prism .Simple .adapt ;
28
+ import static com .jnape .palatable .lambda .optics .functions .Matching .matching ;
29
+ import static com .jnape .palatable .lambda .optics .functions .Re .re ;
30
+
20
31
/**
21
32
* Prisms are {@link Iso Isos} that can fail in one direction. Example:
22
33
* <pre>
42
53
* @param <B> the input that guarantees its output
43
54
*/
44
55
@ FunctionalInterface
45
- public interface Prism <S , T , A , B > extends
46
- ProtoOptic <Cocartesian <?, ?, ?>, S , T , A , B >,
47
- Optic <Cocartesian <?, ?, ?>, Identity <?>, S , T , A , B > {
56
+ public interface Prism <S , T , A , B > extends ProtoOptic <Cocartesian <?, ?, ?>, S , T , A , B >, Monad <T , Prism <S , ?, A , B >> {
48
57
58
+ /**
59
+ * Recover the two mappings encapsulated by this {@link Prism} by sending it through a {@link Market}.
60
+ *
61
+ * @return a {@link Tuple2 tuple} of the two mappings encapsulated by this {@link Prism}
62
+ */
63
+ default Tuple2 <Fn1 <? super B , ? extends T >, Fn1 <? super S , ? extends Either <T , A >>> unPrism () {
64
+ return Tuple2 .fill (this .<Market <A , B , ?, ?>, Identity <?>, Identity <B >, Identity <T >,
65
+ Market <A , B , A , Identity <B >>, Market <A , B , S , Identity <T >>>apply (
66
+ new Market <>(Identity ::new , Either ::right )).fmap (Identity ::runIdentity ))
67
+ .biMap (Market ::bt , Market ::sta );
68
+ }
69
+
70
+ /**
71
+ * {@inheritDoc}
72
+ */
49
73
@ Override
50
74
default <CoP extends Profunctor <?, ?, ? extends Cocartesian <?, ?, ?>>,
51
75
CoF extends Functor <?, ? extends Identity <?>>,
@@ -58,15 +82,62 @@ public interface Prism<S, T, A, B> extends
58
82
}
59
83
60
84
/**
61
- * Recover the two mappings encapsulated by this {@link Prism} by sending it through a {@link Market}.
62
- *
63
- * @return a {@link Tuple2 tuple} of the two mappings encapsulated by this {@link Prism}
85
+ * {@inheritDoc}
64
86
*/
65
- default Tuple2 <Fn1 <? super B , ? extends T >, Fn1 <? super S , ? extends Either <T , A >>> unPrism () {
66
- return Tuple2 .fill (this .<Market <A , B , ?, ?>, Identity <?>, Identity <B >, Identity <T >,
67
- Market <A , B , A , Identity <B >>, Market <A , B , S , Identity <T >>>apply (
68
- new Market <>(Identity ::new , Either ::right )).fmap (Identity ::runIdentity ))
69
- .biMap (Market ::bt , Market ::sta );
87
+ @ Override
88
+ default <U > Prism <S , U , A , B > pure (U u ) {
89
+ return prism (constantly (left (u )), constantly (u ));
90
+ }
91
+
92
+ /**
93
+ * {@inheritDoc}
94
+ */
95
+ @ Override
96
+ default <U > Prism <S , U , A , B > flatMap (Fn1 <? super T , ? extends Monad <U , Prism <S , ?, A , B >>> f ) {
97
+ return unPrism ().into ((bt , seta ) -> prism (
98
+ s -> seta .apply (s ).match (t -> matching (f .apply (t ).<Prism <S , U , A , B >>coerce (), s ), Either ::right ),
99
+ b -> View .<B , B , U , U >view (re (f .apply (bt .apply (b )).coerce ())).apply (b )));
100
+ }
101
+
102
+ /**
103
+ * {@inheritDoc}
104
+ */
105
+ @ Override
106
+ default <U > Prism <S , U , A , B > fmap (Fn1 <? super T , ? extends U > fn ) {
107
+ return Monad .super .<U >fmap (fn ).coerce ();
108
+ }
109
+
110
+ /**
111
+ * {@inheritDoc}
112
+ */
113
+ @ Override
114
+ default <U > Prism <S , U , A , B > zip (Applicative <Fn1 <? super T , ? extends U >, Prism <S , ?, A , B >> appFn ) {
115
+ return Monad .super .zip (appFn ).coerce ();
116
+ }
117
+
118
+ /**
119
+ * {@inheritDoc}
120
+ */
121
+ @ Override
122
+ default <U > Lazy <Prism <S , U , A , B >> lazyZip (
123
+ Lazy <? extends Applicative <Fn1 <? super T , ? extends U >, Prism <S , ?, A , B >>> lazyAppFn ) {
124
+ return Monad .super .lazyZip (lazyAppFn ).fmap (Monad <U , Prism <S , ?, A , B >>::coerce );
125
+ }
126
+
127
+ /**
128
+ * {@inheritDoc}
129
+ */
130
+ @ Override
131
+ default <U > Prism <S , U , A , B > discardL (Applicative <U , Prism <S , ?, A , B >> appB ) {
132
+ return Monad .super .discardL (appB ).coerce ();
133
+ }
134
+
135
+ /**
136
+ * {@inheritDoc}
137
+ */
138
+ @ Override
139
+ default <U > Prism <S , T , A , B > discardR (Applicative <U , Prism <S , ?, A , B >> appB ) {
140
+ return Monad .super .discardR (appB ).coerce ();
70
141
}
71
142
72
143
/**
@@ -85,8 +156,7 @@ static <S, T, A, B> Prism<S, T, A, B> prism(Fn1<? super S, ? extends CoProduct2<
85
156
Fn1 <? super B , ? extends T > bt ) {
86
157
return new Prism <S , T , A , B >() {
87
158
@ Override
88
- public <F extends Functor <?, ? extends F >> Optic <Cocartesian <?, ?, ?>, F , S , T , A , B > toOptic (
89
- Pure <? extends F > pure ) {
159
+ public <F extends Applicative <?, F >> Optic <Cocartesian <?, ?, ?>, F , S , T , A , B > toOptic (Pure <F > pure ) {
90
160
return Optic .<Cocartesian <?, ?, ?>,
91
161
F ,
92
162
S , T , A , B ,
@@ -113,8 +183,7 @@ static <S, T, A, B> Prism<S, T, A, B> prism(Fn1<? super S, ? extends CoProduct2<
113
183
static <S , T , A , B > Prism <S , T , A , B > prism (ProtoOptic <? super Cocartesian <?, ?, ?>, S , T , A , B > protoOptic ) {
114
184
return new Prism <S , T , A , B >() {
115
185
@ Override
116
- public <F extends Functor <?, ? extends F >> Optic <Cocartesian <?, ?, ?>, F , S , T , A , B > toOptic (
117
- Pure <? extends F > pure ) {
186
+ public <F extends Applicative <?, F >> Optic <Cocartesian <?, ?, ?>, F , S , T , A , B > toOptic (Pure <F > pure ) {
118
187
Optic <? super Cocartesian <?, ?, ?>, F , S , T , A , B > optic = protoOptic .toOptic (pure );
119
188
return Optic .reframe (optic );
120
189
}
@@ -138,8 +207,7 @@ static <S, T, A, B> Prism<S, T, A, B> prism(
138
207
Optic <? super Cocartesian <?, ?, ?>, ? super Functor <?, ?>, S , T , A , B > optic ) {
139
208
return new Prism <S , T , A , B >() {
140
209
@ Override
141
- public <F extends Functor <?, ? extends F >> Optic <Cocartesian <?, ?, ?>, F , S , T , A , B > toOptic (
142
- Pure <? extends F > pure ) {
210
+ public <F extends Applicative <?, F >> Optic <Cocartesian <?, ?, ?>, F , S , T , A , B > toOptic (Pure <F > pure ) {
143
211
return Optic .reframe (optic );
144
212
}
145
213
};
@@ -160,6 +228,12 @@ static <S, A> Prism.Simple<S, A> simplePrism(Fn1<? super S, ? extends Maybe<A>>
160
228
return Prism .<S , S , A , A >prism (s -> sMaybeA .apply (s ).toEither (() -> s ), as )::toOptic ;
161
229
}
162
230
231
+
232
+ static <S , A > Prism .Simple <S , A > fromPartial (Fn1 <? super S , ? extends A > partialSa ,
233
+ Fn1 <? super A , ? extends S > as ) {
234
+ return adapt (prism (partialSa .<S , A >diMap (downcast (), upcast ()).choose (), as ));
235
+ }
236
+
163
237
/**
164
238
* A convenience type with a simplified type signature for common {@link Prism prism} with unified <code>S/T</code>
165
239
* and <code>A/B</code> types.
0 commit comments