Skip to content

Commit 71ee383

Browse files
committed
Adding #project for coproducts
1 parent 352d094 commit 71ee383

File tree

8 files changed

+109
-1
lines changed

8 files changed

+109
-1
lines changed

src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct2.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
package com.jnape.palatable.lambda.adt.coproduct;
22

3+
import com.jnape.palatable.lambda.adt.hlist.Tuple2;
34
import com.jnape.palatable.lambda.functor.Bifunctor;
45
import com.jnape.palatable.lambda.functor.Functor;
56

67
import java.util.Objects;
8+
import java.util.Optional;
79
import java.util.function.Function;
810

11+
import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
12+
913
/**
1014
* A generalization of the coproduct of two types <code>A</code> and <code>B</code>. Coproducts represent the disjoint
1115
* union of two or more distinct types, and provides an interface for specifying morphisms from those types to a common
@@ -58,6 +62,17 @@ default <C> CoProduct3<A, B, C> diverge() {
5862
return match(CoProduct3::a, CoProduct3::b);
5963
}
6064

65+
/**
66+
* Project this coproduct onto a tuple, such that the slot in the tuple that corresponds to this coproduct's value
67+
* is present, while the other slots are absent.
68+
*
69+
* @return a tuple of the coproduct projection
70+
*/
71+
default Tuple2<Optional<A>, Optional<B>> project() {
72+
return match(a -> tuple(Optional.of(a), Optional.empty()),
73+
b -> tuple(Optional.empty(), Optional.of(b)));
74+
}
75+
6176
@Override
6277
default <C> CoProduct2<A, C> fmap(Function<? super B, ? extends C> fn) {
6378
return biMapR(fn);

src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct3.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
package com.jnape.palatable.lambda.adt.coproduct;
22

3+
import com.jnape.palatable.lambda.adt.hlist.Tuple3;
34
import com.jnape.palatable.lambda.functor.Bifunctor;
45
import com.jnape.palatable.lambda.functor.Functor;
56

67
import java.util.Objects;
8+
import java.util.Optional;
79
import java.util.function.Function;
810

11+
import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
12+
913
/**
1014
* A generalization of the coproduct of three types <code>A</code>, <code>B</code>, and <code>C</code>.
1115
*
@@ -30,7 +34,6 @@ public interface CoProduct3<A, B, C> extends Functor<C>, Bifunctor<B, C> {
3034
<R> R match(Function<? super A, ? extends R> aFn, Function<? super B, ? extends R> bFn,
3135
Function<? super C, ? extends R> cFn);
3236

33-
3437
/**
3538
* Diverge this coproduct by introducing another possible type that it could represent.
3639
*
@@ -42,6 +45,18 @@ default <D> CoProduct4<A, B, C, D> diverge() {
4245
return match(CoProduct4::a, CoProduct4::b, CoProduct4::c);
4346
}
4447

48+
/**
49+
* Project this coproduct onto a tuple.
50+
*
51+
* @return a tuple of the coproduct projection
52+
* @see CoProduct2#project()
53+
*/
54+
default Tuple3<Optional<A>, Optional<B>, Optional<C>> project() {
55+
return match(a -> tuple(Optional.of(a), Optional.empty(), Optional.empty()),
56+
b -> tuple(Optional.empty(), Optional.of(b), Optional.empty()),
57+
c -> tuple(Optional.empty(), Optional.empty(), Optional.of(c)));
58+
}
59+
4560
@Override
4661
default <D> CoProduct3<A, B, D> fmap(Function<? super C, ? extends D> fn) {
4762
return biMapR(fn);

src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct4.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
package com.jnape.palatable.lambda.adt.coproduct;
22

3+
import com.jnape.palatable.lambda.adt.hlist.Tuple4;
34
import com.jnape.palatable.lambda.functor.Bifunctor;
45
import com.jnape.palatable.lambda.functor.Functor;
56

67
import java.util.Objects;
8+
import java.util.Optional;
79
import java.util.function.Function;
810

11+
import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
12+
913
/**
1014
* A generalization of the coproduct of four types <code>A</code>, <code>B</code>, <code>C</code>, and <code>D</code>.
1115
*
@@ -45,6 +49,19 @@ default <E> CoProduct5<A, B, C, D, E> diverge() {
4549
return match(CoProduct5::a, CoProduct5::b, CoProduct5::c, CoProduct5::d);
4650
}
4751

52+
/**
53+
* Project this coproduct onto a tuple.
54+
*
55+
* @return a tuple of the coproduct projection
56+
* @see CoProduct2#project()
57+
*/
58+
default Tuple4<Optional<A>, Optional<B>, Optional<C>, Optional<D>> project() {
59+
return match(a -> tuple(Optional.of(a), Optional.empty(), Optional.empty(), Optional.empty()),
60+
b -> tuple(Optional.empty(), Optional.of(b), Optional.empty(), Optional.empty()),
61+
c -> tuple(Optional.empty(), Optional.empty(), Optional.of(c), Optional.empty()),
62+
d -> tuple(Optional.empty(), Optional.empty(), Optional.empty(), Optional.of(d)));
63+
}
64+
4865
@Override
4966
default <E> CoProduct4<A, B, C, E> fmap(Function<? super D, ? extends E> fn) {
5067
return biMapR(fn);

src/main/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct5.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
package com.jnape.palatable.lambda.adt.coproduct;
22

3+
import com.jnape.palatable.lambda.adt.hlist.Tuple5;
34
import com.jnape.palatable.lambda.functor.Bifunctor;
45
import com.jnape.palatable.lambda.functor.Functor;
56

67
import java.util.Objects;
8+
import java.util.Optional;
79
import java.util.function.Function;
810

11+
import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
12+
913
/**
1014
* A generalization of the coproduct of five types <code>A</code>, <code>B</code>, <code>C</code>, <code>D</code>, and
1115
* <code>E</code>.
@@ -38,6 +42,20 @@ <R> R match(Function<? super A, ? extends R> aFn,
3842
Function<? super D, ? extends R> dFn,
3943
Function<? super E, ? extends R> eFn);
4044

45+
/**
46+
* Project this coproduct onto a tuple.
47+
*
48+
* @return a tuple of the coproduct projection
49+
* @see CoProduct2#project()
50+
*/
51+
default Tuple5<Optional<A>, Optional<B>, Optional<C>, Optional<D>, Optional<E>> project() {
52+
return match(a -> tuple(Optional.of(a), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty()),
53+
b -> tuple(Optional.empty(), Optional.of(b), Optional.empty(), Optional.empty(), Optional.empty()),
54+
c -> tuple(Optional.empty(), Optional.empty(), Optional.of(c), Optional.empty(), Optional.empty()),
55+
d -> tuple(Optional.empty(), Optional.empty(), Optional.empty(), Optional.of(d), Optional.empty()),
56+
e -> tuple(Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.of(e)));
57+
}
58+
4159
@Override
4260
default <F> CoProduct5<A, B, C, D, F> fmap(Function<? super E, ? extends F> fn) {
4361
return biMapR(fn);

src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct2Test.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@
33
import org.junit.Before;
44
import org.junit.Test;
55

6+
import java.util.Optional;
7+
68
import static com.jnape.palatable.lambda.adt.coproduct.CoProduct2.a;
79
import static com.jnape.palatable.lambda.adt.coproduct.CoProduct2.b;
10+
import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
811
import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id;
912
import static org.junit.Assert.assertEquals;
1013

@@ -31,6 +34,12 @@ public void diverge() {
3134
assertEquals(CoProduct3.b(true), b.diverge());
3235
}
3336

37+
@Test
38+
public void project() {
39+
assertEquals(tuple(Optional.of(1), Optional.empty()), CoProduct2.a(1).project());
40+
assertEquals(tuple(Optional.empty(), Optional.of("b")), CoProduct2.b("b").project());
41+
}
42+
3443
@Test
3544
public void functorProperties() {
3645
assertEquals(a, a.fmap(bool -> !bool));

src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct3Test.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33
import org.junit.Before;
44
import org.junit.Test;
55

6+
import java.util.Optional;
7+
68
import static com.jnape.palatable.lambda.adt.coproduct.CoProduct3.a;
79
import static com.jnape.palatable.lambda.adt.coproduct.CoProduct3.b;
810
import static com.jnape.palatable.lambda.adt.coproduct.CoProduct3.c;
11+
import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
912
import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id;
1013
import static org.junit.Assert.assertEquals;
1114

@@ -36,6 +39,13 @@ public void diverge() {
3639
assertEquals(CoProduct4.c(true), c.diverge());
3740
}
3841

42+
@Test
43+
public void project() {
44+
assertEquals(tuple(Optional.of(1), Optional.empty(), Optional.empty()), CoProduct3.a(1).project());
45+
assertEquals(tuple(Optional.empty(), Optional.of("b"), Optional.empty()), CoProduct3.b("b").project());
46+
assertEquals(tuple(Optional.empty(), Optional.empty(), Optional.of('c')), CoProduct3.c('c').project());
47+
}
48+
3949
@Test
4050
public void functorProperties() {
4151
assertEquals(a, a.fmap(bool -> !bool));

src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct4Test.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33
import org.junit.Before;
44
import org.junit.Test;
55

6+
import java.util.Optional;
7+
68
import static com.jnape.palatable.lambda.adt.coproduct.CoProduct4.a;
79
import static com.jnape.palatable.lambda.adt.coproduct.CoProduct4.b;
810
import static com.jnape.palatable.lambda.adt.coproduct.CoProduct4.c;
911
import static com.jnape.palatable.lambda.adt.coproduct.CoProduct4.d;
12+
import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
1013
import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id;
1114
import static org.junit.Assert.assertEquals;
1215

@@ -41,6 +44,14 @@ public void diverge() {
4144
assertEquals(CoProduct5.d(4D), d.diverge());
4245
}
4346

47+
@Test
48+
public void project() {
49+
assertEquals(tuple(Optional.of(1), Optional.empty(), Optional.empty(), Optional.empty()), CoProduct4.a(1).project());
50+
assertEquals(tuple(Optional.empty(), Optional.of("b"), Optional.empty(), Optional.empty()), CoProduct4.b("b").project());
51+
assertEquals(tuple(Optional.empty(), Optional.empty(), Optional.of('c'), Optional.empty()), CoProduct4.c('c').project());
52+
assertEquals(tuple(Optional.empty(), Optional.empty(), Optional.empty(), Optional.of(4L)), CoProduct4.d(4L).project());
53+
}
54+
4455
@Test
4556
public void functorProperties() {
4657
assertEquals(a, a.fmap(d -> -d));

src/test/java/com/jnape/palatable/lambda/adt/coproduct/CoProduct5Test.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33
import org.junit.Before;
44
import org.junit.Test;
55

6+
import java.util.Optional;
7+
68
import static com.jnape.palatable.lambda.adt.coproduct.CoProduct5.a;
79
import static com.jnape.palatable.lambda.adt.coproduct.CoProduct5.b;
810
import static com.jnape.palatable.lambda.adt.coproduct.CoProduct5.c;
911
import static com.jnape.palatable.lambda.adt.coproduct.CoProduct5.d;
1012
import static com.jnape.palatable.lambda.adt.coproduct.CoProduct5.e;
13+
import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
1114
import static com.jnape.palatable.lambda.functions.builtin.fn1.Id.id;
1215
import static org.junit.Assert.assertEquals;
1316

@@ -37,6 +40,16 @@ public void match() {
3740
assertEquals('z', e.match(id(), id(), id(), id(), id()));
3841
}
3942

43+
@Test
44+
public void project() {
45+
assertEquals(tuple(Optional.of(1), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty()), CoProduct5.a(1).project());
46+
assertEquals(tuple(Optional.empty(), Optional.of("b"), Optional.empty(), Optional.empty(), Optional.empty()), CoProduct5.b("b").project());
47+
assertEquals(tuple(Optional.empty(), Optional.empty(), Optional.of('c'), Optional.empty(), Optional.empty()), CoProduct5.c('c').project());
48+
assertEquals(tuple(Optional.empty(), Optional.empty(), Optional.empty(), Optional.of(4L), Optional.empty()), CoProduct5.d(4L).project());
49+
assertEquals(tuple(Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.of(false)), CoProduct5.e(false).project());
50+
}
51+
52+
4053
@Test
4154
public void functorProperties() {
4255
assertEquals(a, a.fmap(Character::toUpperCase));

0 commit comments

Comments
 (0)