Skip to content

Commit 7d3f613

Browse files
committed
Implemented left and middle projections of Either3.
1 parent ef79720 commit 7d3f613

File tree

1 file changed

+279
-7
lines changed

1 file changed

+279
-7
lines changed

core/src/main/java/fj/data/Either3.java

Lines changed: 279 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
package fj.data;
22

3-
import fj.Equal;
4-
import fj.F;
5-
import fj.Hash;
3+
import fj.*;
4+
import fj.function.Effect1;
65

6+
import java.util.Collection;
7+
import java.util.Iterator;
8+
9+
import static fj.Function.identity;
10+
import static fj.P.p;
11+
import static fj.Unit.unit;
12+
import static fj.data.Array.mkArray;
13+
import static fj.data.List.*;
714
import static fj.data.Option.none;
815
import static fj.data.Option.some;
916

@@ -49,6 +56,8 @@ public <D> D either(F<A, D> fa, F<B, D> fb, F<C, D> fc) {
4956
return fc.f(c);
5057
}
5158

59+
60+
5261
}
5362

5463
public static final class LeftProjection<A, B, C> {
@@ -62,23 +71,121 @@ public <X> Either3<X, B, C> apply(final Either3<F<A, X>, B, C> e) {
6271
return e.left().bind(this::map);
6372
}
6473

65-
public boolean exists(final F<A, Boolean> f) {
66-
return e.either(a -> f.f(a), b -> false, c -> false);
67-
}
68-
6974
public <X> Either3<X, B, C> bind(F<A, Either3<X, B, C>> f) {
7075
return e.either(a -> f.f(a), b -> middle(b), c -> right(c));
7176
}
7277

78+
public Either3<A, B, C> either() {
79+
return e;
80+
}
81+
82+
public boolean exists(final F<A, Boolean> f) {
83+
return e.either(a -> f.f(a), b -> false, c -> false);
84+
}
85+
7386
public <X, Y> Option<Either3<A, X, Y>> filter(final F<A, Boolean> f) {
7487
return e.either(a -> f.f(a) ? some(left(a)) : none(), b -> none(), c -> none());
7588
}
7689

90+
public boolean forall(final F<A, Boolean> f) {
91+
return e.either(a -> f.f(a), b -> true, c -> true);
92+
}
93+
94+
public Unit foreach(final F<A, Unit> f) {
95+
return e.either(a -> f.f(a), b -> unit(), c -> unit());
96+
}
97+
98+
public void foreachDoEffect(final Effect1<A> f) {
99+
e.either(a -> f.toF().f(a), b -> unit(), c -> unit());
100+
}
101+
102+
public Iterator<A> iterator() {
103+
return toList().iterator();
104+
}
77105

78106
public <X> Either3<X, B, C> map(final F<A, X> f) {
79107
return e.either(a -> left(f.f(a)), b -> middle(b), c -> right(c));
80108
}
81109

110+
public A orValue(final A value) {
111+
return orValue(() -> value);
112+
}
113+
114+
public A orValue(final F0<A> f) {
115+
return e.either(a -> a, b -> f.f(), c -> f.f());
116+
}
117+
118+
public <X> Either3<X, B, C> sequence(final Either3<X, B, C> e) {
119+
return bind(Function.constant(e));
120+
}
121+
122+
public Array<A> toArray() {
123+
return e.either(
124+
a -> Array.single(a),
125+
b -> Array.empty(),
126+
c -> Array.empty()
127+
);
128+
}
129+
130+
public Collection<A> toCollection() {
131+
return toList().toCollection();
132+
}
133+
134+
public List<A> toList() {
135+
return e.either(a -> single(a), b -> nil(), c -> nil());
136+
}
137+
138+
public Option<A> toOption() {
139+
return e.either(a -> some(a), b -> none(), c -> none());
140+
}
141+
142+
public Stream<A> toStream() {
143+
return e.either(a -> Stream.single(a), b -> Stream.nil(), c -> Stream.nil());
144+
}
145+
146+
public <X> IO<Either3<X, B, C>> traverseIO(final F<A, IO<X>> f) {
147+
return e.either(
148+
a -> f.f(a).map(Either3::left),
149+
b -> IOFunctions.unit(middle(b)),
150+
c -> IOFunctions.unit(right(c))
151+
);
152+
}
153+
154+
public <X> List<Either3<X, B, C>> traverseList1(final F<A, List<X>> f) {
155+
return e.either(
156+
a -> f.f(a).map(Either3::left),
157+
b -> single(middle(b)),
158+
c -> single(right(c))
159+
);
160+
}
161+
162+
public <X> Option<Either3<X, B, C>> traverseOption(final F<A, Option<X>> f) {
163+
return e.either(
164+
a -> f.f(a).map(Either3::left),
165+
b -> some(middle(b)),
166+
c -> some(right(c))
167+
);
168+
169+
}
170+
171+
public <X> P1<Either3<X, B, C>> traverseP1(final F<A, P1<X>> f) {
172+
return e.either(
173+
a -> f.f(a).map(Either3::left),
174+
b -> p(middle(b)),
175+
c -> p(right(c))
176+
);
177+
178+
}
179+
180+
public <X> Stream<Either3<X, B, C>> traverseStream(final F<A, Stream<X>> f) {
181+
return e.either(
182+
a -> f.f(a).map(Either3::left),
183+
b -> Stream.single(middle(b)),
184+
c -> Stream.single(right(c))
185+
);
186+
187+
}
188+
82189
}
83190

84191
public static final class MiddleProjection<A, B, C> {
@@ -88,10 +195,150 @@ private MiddleProjection(final Either3<A, B, C> e) {
88195
this.e = e;
89196
}
90197

198+
public <X> Either3<A, X, C> apply(final Either3<A, F<B, X>, C> e) {
199+
return e.middle().bind(this::map);
200+
}
201+
91202
public <X> Either3<A, X, C> bind(F<B, Either3<A, X, C>> f) {
92203
return e.either(a -> left(a), b -> f.f(b), c -> right(c));
93204
}
94205

206+
public Either3<A, B, C> either() {
207+
return e;
208+
}
209+
210+
public boolean exists(final F<B, Boolean> f) {
211+
return e.either(a -> false, b -> f.f(b), c -> false);
212+
}
213+
214+
public <X, Y> Option<Either3<X, B, Y>> filter(final F<B, Boolean> f) {
215+
return e.either(a -> none(), b -> f.f(b) ? some(middle(b)) : none(), c -> none());
216+
}
217+
218+
public boolean forall(final F<B, Boolean> f) {
219+
return e.either(a -> true, b -> f.f(b), c -> true);
220+
}
221+
222+
public Unit foreach(final F<B, Unit> f) {
223+
return e.either(a -> unit(), b -> f.f(b), c -> unit());
224+
}
225+
226+
public void foreachDoEffect(final Effect1<B> f) {
227+
e.either(a -> unit(), b -> f.toF().f(b), c -> unit());
228+
}
229+
230+
public Iterator<B> iterator() {
231+
return toList().iterator();
232+
}
233+
234+
public <X> Either3<A, X, C> map(final F<B, X> f) {
235+
return e.either(a -> left(a), b -> middle(f.f(b)), c -> right(c));
236+
}
237+
238+
public B orValue(final B value) {
239+
return orValue(() -> value);
240+
}
241+
242+
public B orValue(final F0<B> f) {
243+
return e.either(a -> f.f(), b -> b, c -> f.f());
244+
}
245+
246+
public <X> Either3<A, X, C> sequence(final Either3<A, X, C> e) {
247+
return bind(Function.constant(e));
248+
}
249+
250+
public Array<B> toArray() {
251+
return e.either(
252+
a -> Array.empty(),
253+
b -> Array.single(b),
254+
c -> Array.empty()
255+
);
256+
}
257+
258+
public Collection<B> toCollection() {
259+
return toList().toCollection();
260+
}
261+
262+
public List<B> toList() {
263+
return e.either(a -> nil(), b -> single(b), c -> nil());
264+
}
265+
266+
public Option<B> toOption() {
267+
return e.either(a -> none(), b -> some(b), c -> none());
268+
}
269+
270+
public Stream<B> toStream() {
271+
return e.either(a -> Stream.nil(), b -> Stream.single(b), c -> Stream.nil());
272+
}
273+
274+
public <X> IO<Either3<A, X, C>> traverseIO(final F<B, IO<X>> f) {
275+
return e.either(
276+
a -> IOFunctions.unit(left(a)),
277+
b -> f.f(b).map(Either3::middle),
278+
c -> IOFunctions.unit(right(c))
279+
);
280+
}
281+
282+
public <X> List<Either3<A, X, C>> traverseList1(final F<B, List<X>> f) {
283+
return e.either(
284+
a -> single(left(a)),
285+
b -> f.f(b).map(Either3::middle),
286+
c -> single(right(c))
287+
);
288+
}
289+
290+
public <X> Option<Either3<A, X, C>> traverseOption(final F<B, Option<X>> f) {
291+
return e.either(
292+
a -> some(left(a)),
293+
b -> f.f(b).map(Either3::middle),
294+
c -> some(right(c))
295+
);
296+
297+
}
298+
299+
public <X> P1<Either3<A, X, C>> traverseP1(final F<B, P1<X>> f) {
300+
return e.either(
301+
a -> p(left(a)),
302+
b -> f.f(b).map(Either3::middle),
303+
c -> p(right(c))
304+
);
305+
306+
}
307+
308+
public <X> Stream<Either3<A, X, C>> traverseStream(final F<B, Stream<X>> f) {
309+
return e.either(
310+
a -> Stream.single(left(a)),
311+
b -> f.f(b).map(Either3::middle),
312+
c -> Stream.single(right(c))
313+
);
314+
315+
}
316+
317+
318+
}
319+
320+
public final <X> Either3<X, B, C> leftMap(F<A, X> f) {
321+
return left().map(f);
322+
}
323+
324+
public final <X> F<F<A, X>, Either3<X, B, C>> leftMap_() {
325+
return this::leftMap;
326+
}
327+
328+
public final <X> Either3<A, X, C> middleMap(F<B, X> f) {
329+
return middle().map(f);
330+
}
331+
332+
public final <X> F<F<B, X>, Either3<A, X, C>> middleMap_() {
333+
return this::middleMap;
334+
}
335+
336+
public final <X> Either3<A, B, X> rightMap(F<C, X> f) {
337+
return right().map(f);
338+
}
339+
340+
public final <X> F<F<C, X>, Either3<A, B, X>> rightMap_() {
341+
return this::rightMap;
95342
}
96343

97344
public static final class RightProjection<A, B, C> {
@@ -104,12 +351,21 @@ private RightProjection(final Either3<A, B, C> e) {
104351
public <X> Either3<A, B, X> bind(F<C, Either3<A, B, X>> f) {
105352
return e.either(a -> left(a), b -> middle(b), c -> f.f(c));
106353
}
354+
355+
public <X> Either3<A, B, X> map(final F<C, X> f) {
356+
return e.either(a -> left(a), b -> middle(b), c -> right(f.f(c)));
357+
}
358+
107359
}
108360

109361
public static <A, B, C> Either3<A, B, C> left(A a) {
110362
return new Left<>(a);
111363
}
112364

365+
public static <A, B, C> F<A, Either3<A, B, C>> left_() {
366+
return Either3::left;
367+
}
368+
113369
public static <A, B, C> Either3<A, B, C> middle(B b) {
114370
return new Middle<>(b);
115371
}
@@ -140,6 +396,22 @@ public <X, Y, Z> Either3<X, Y, Z> map3(F<A, X> fl, F<B, Y> fm, F<C, Z> fr) {
140396

141397
public abstract <D> D either(F<A, D> fa, F<B, D> fb, F<C, D> fc);
142398

399+
public static <A, B, C, D> F<Either3<A, B, C>, D> either_(F<A, D> fa, F<B, D> fb, F<C, D> fc) {
400+
return e -> e.either(fa, fb, fc);
401+
}
402+
403+
public static <A, B, C> Either3<A, B, C> joinLeft(final Either3<Either3<A, B, C>, B, C> e) {
404+
return e.left().bind(identity());
405+
}
406+
407+
public static <A, B, C> Either3<A, B, C> joinMiddle(final Either3<A, Either3<A, B, C>, C> e) {
408+
return e.middle().bind(identity());
409+
}
410+
411+
public static <A, B, C> Either3<A, B, C> joinRight(final Either3<A, B, Either3<A, B, C>> e) {
412+
return e.right().bind(identity());
413+
}
414+
143415
public Either3<B, C, A> moveLeft() {
144416
return either(a -> right(a), b -> left(b), c -> middle(c));
145417
}

0 commit comments

Comments
 (0)