Skip to content

Commit a950e87

Browse files
committed
Moving semigroups and monoids under fn2 for better discoverability; various renaming.
Adding Monoid/Semigroup factory specializations of Fn3, adding Fn4 for Bi-specializations, and condensing dual semigroup and monoid function types into single classes with specific static factory methods. monoid/semigroups include: - LeftAll - RightAll - LeftAny - RightAny - Concat - Collapse - Merge - Present - PutAll
1 parent 474e8a9 commit a950e87

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1488
-177
lines changed

src/main/java/com/jnape/palatable/lambda/adt/hlist/Tuple2.java

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

33
import com.jnape.palatable.lambda.adt.hlist.HList.HCons;
4+
import com.jnape.palatable.lambda.monoid.Monoid;
45
import com.jnape.palatable.lambda.functor.Bifunctor;
56
import com.jnape.palatable.lambda.functor.Functor;
67

@@ -90,6 +91,13 @@ public <_1Prime, _2Prime> Tuple2<_1Prime, _2Prime> biMap(Function<? super _1, ?
9091
return new Tuple2<>(lFn.apply(_1()), tail().fmap(rFn));
9192
}
9293

94+
public static <_1, _2> Monoid<Tuple2<_1, _2>> monoid(Monoid<_1> _1Monoid, Monoid<_2> _2Monoid) {
95+
return Monoid.monoid(
96+
(x, y) -> x.biMap(_1Monoid.flip().apply(y._1()),
97+
_2Monoid.flip().apply(y._2())),
98+
tuple(_1Monoid.identity(), _2Monoid.identity()));
99+
}
100+
93101
/**
94102
* Static factory method for creating <code>Tuple2</code>s from {@link java.util.Map.Entry}s.
95103
*
@@ -101,4 +109,5 @@ public <_1Prime, _2Prime> Tuple2<_1Prime, _2Prime> biMap(Function<? super _1, ?
101109
public static <K, V> Tuple2<K, V> fromEntry(Map.Entry<K, V> entry) {
102110
return new Tuple2<>(entry.getKey(), singletonHList(entry.getValue()));
103111
}
112+
104113
}

src/main/java/com/jnape/palatable/lambda/functions/Fn2.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
* @param <B> The second argument type
1414
* @param <C> The return type
1515
* @see Fn1
16-
* @see com.jnape.palatable.lambda.functions.builtin.fn2.Partial2
1716
*/
1817
@FunctionalInterface
1918
public interface Fn2<A, B, C> extends Fn1<A, Fn1<B, C>> {

src/main/java/com/jnape/palatable/lambda/functions/Fn3.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
* @param <C> The third argument type
1111
* @param <D> The return type
1212
* @see Fn2
13-
* @see com.jnape.palatable.lambda.functions.builtin.fn2.Partial3
1413
*/
1514
@FunctionalInterface
1615
public interface Fn3<A, B, C, D> extends Fn2<A, B, Fn1<C, D>> {
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package com.jnape.palatable.lambda.functions;
2+
3+
import com.jnape.palatable.lambda.adt.hlist.Tuple2;
4+
5+
/**
6+
* A function taking four arguments. Defined in terms of <code>Fn3</code>, so similarly auto-curried.
7+
*
8+
* @param <A> The first argument type
9+
* @param <B> The second argument type
10+
* @param <C> The third argument type
11+
* @param <D> The fourth argument type
12+
* @param <E> The return type
13+
* @see Fn3
14+
*/
15+
@FunctionalInterface
16+
public interface Fn4<A, B, C, D, E> extends Fn3<A, B, C, Fn1<D, E>> {
17+
18+
/**
19+
* Invoke this function with the given arguments.
20+
*
21+
* @param a the first argument
22+
* @param b the second argument
23+
* @param c the third argument
24+
* @param d the fourth argument
25+
* @return the result of the function application
26+
*/
27+
E apply(A a, B b, C c, D d);
28+
29+
/**
30+
* Partially apply this function by taking its first argument.
31+
*
32+
* @param a the first argument
33+
* @return an Fn3 that takes the second, third, and fourth argument and returns the result
34+
*/
35+
@Override
36+
default Fn3<B, C, D, E> apply(A a) {
37+
return (b, c, d) -> apply(a, b, c, d);
38+
}
39+
40+
/**
41+
* Partially apply this function by taking its first two arguments.
42+
*
43+
* @param a the first argument
44+
* @param b the second argument
45+
* @return an Fn2 that takes the third and fourth arguments and returns the result
46+
*/
47+
@Override
48+
default Fn2<C, D, E> apply(A a, B b) {
49+
return (c, d) -> apply(a, b, c, d);
50+
}
51+
52+
/**
53+
* Partially apply this function by taking its first three arguments.
54+
*
55+
* @param a the first argument
56+
* @param b the second argument
57+
* @param c the third argument
58+
* @return an Fn1 that takes the fourth argument and returns the result
59+
*/
60+
@Override
61+
default Fn1<D, E> apply(A a, B b, C c) {
62+
return (d) -> apply(a, b, c, d);
63+
}
64+
65+
/**
66+
* Flip the order of the first two arguments.
67+
*
68+
* @return an Fn3 that takes the first and second arguments in reversed order
69+
*/
70+
@Override
71+
default Fn4<B, A, C, D, E> flip() {
72+
return (b, a, c, d) -> apply(a, b, c, d);
73+
}
74+
75+
/**
76+
* Returns an <code>Fn3</code> that takes the first two arguments as a <code>Tuple2&lt;A, B&gt;</code> and the third
77+
* and fourth arguments.
78+
*
79+
* @return an Fn3 taking a Tuple2 and the third and fourth arguments
80+
*/
81+
@Override
82+
default Fn3<Tuple2<A, B>, C, D, E> uncurry() {
83+
return (ab, c, d) -> apply(ab._1(), ab._2(), c, d);
84+
}
85+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.jnape.palatable.lambda.functions.specialized;
2+
3+
import com.jnape.palatable.lambda.adt.hlist.Tuple2;
4+
import com.jnape.palatable.lambda.monoid.Monoid;
5+
6+
@FunctionalInterface
7+
public interface BiMonoidFactory<A, B, C> extends BiSemigroupFactory<A, B, C> {
8+
9+
@Override
10+
default MonoidFactory<B, C> apply(A a) {
11+
return b -> apply(a, b);
12+
}
13+
14+
@Override
15+
Monoid<C> apply(A a, B b);
16+
17+
@Override
18+
default BiMonoidFactory<B, A, C> flip() {
19+
return (b, a) -> apply(a, b);
20+
}
21+
22+
@Override
23+
default MonoidFactory<Tuple2<A, B>, C> uncurry() {
24+
return ab -> apply(ab._1()).apply(ab._2());
25+
}
26+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.jnape.palatable.lambda.functions.specialized;
2+
3+
import com.jnape.palatable.lambda.adt.hlist.Tuple2;
4+
import com.jnape.palatable.lambda.functions.Fn4;
5+
import com.jnape.palatable.lambda.semigroup.Semigroup;
6+
7+
@FunctionalInterface
8+
public interface BiSemigroupFactory<A, B, C> extends Fn4<A, B, C, C, C> {
9+
10+
@Override
11+
Semigroup<C> apply(A a, B b);
12+
13+
@Override
14+
default SemigroupFactory<B, C> apply(A a) {
15+
return b -> apply(a, b);
16+
}
17+
18+
@Override
19+
default BiSemigroupFactory<B, A, C> flip() {
20+
return (b, a) -> apply(a, b);
21+
}
22+
23+
@Override
24+
default SemigroupFactory<Tuple2<A, B>, C> uncurry() {
25+
return ab -> apply(ab._1(), ab._2());
26+
}
27+
28+
@Override
29+
default C apply(A a, B b, C c, C d) {
30+
return apply(a).apply(b).apply(c, d);
31+
}
32+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.jnape.palatable.lambda.functions.specialized;
2+
3+
import com.jnape.palatable.lambda.monoid.Monoid;
4+
5+
public interface MonoidFactory<A, B> extends SemigroupFactory<A, B> {
6+
7+
@Override
8+
default B apply(A a, B b, B c) {
9+
return apply(a).apply(b, c);
10+
}
11+
12+
@Override
13+
Monoid<B> apply(A a);
14+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.jnape.palatable.lambda.functions.specialized;
2+
3+
import com.jnape.palatable.lambda.functions.Fn3;
4+
import com.jnape.palatable.lambda.semigroup.Semigroup;
5+
6+
@FunctionalInterface
7+
public interface SemigroupFactory<A, B> extends Fn3<A, B, B, B> {
8+
9+
@Override
10+
Semigroup<B> apply(A a);
11+
12+
@Override
13+
default B apply(A a, B b, B c) {
14+
return apply(a).apply(b, c);
15+
}
16+
}

src/main/java/com/jnape/palatable/lambda/monoid/Monoid.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.jnape.palatable.lambda.semigroup.Semigroup;
77

88
import java.util.function.Function;
9+
import java.util.function.Supplier;
910

1011
import static com.jnape.palatable.lambda.functions.builtin.fn2.Map.map;
1112

@@ -84,4 +85,18 @@ public A apply(A x, A y) {
8485
}
8586
};
8687
}
88+
89+
static <A> Monoid<A> monoid(Semigroup<A> semigroup, Supplier<A> identitySupplier) {
90+
return new Monoid<A>() {
91+
@Override
92+
public A identity() {
93+
return identitySupplier.get();
94+
}
95+
96+
@Override
97+
public A apply(A x, A y) {
98+
return semigroup.apply(x, y);
99+
}
100+
};
101+
}
87102
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package com.jnape.palatable.lambda.monoid.builtin;
2+
3+
import com.jnape.palatable.lambda.adt.hlist.Tuple2;
4+
import com.jnape.palatable.lambda.functions.Fn1;
5+
import com.jnape.palatable.lambda.functions.specialized.BiMonoidFactory;
6+
import com.jnape.palatable.lambda.functions.specialized.MonoidFactory;
7+
import com.jnape.palatable.lambda.monoid.Monoid;
8+
import com.jnape.palatable.lambda.semigroup.Semigroup;
9+
10+
import static com.jnape.palatable.lambda.adt.hlist.HList.tuple;
11+
12+
/**
13+
* A {@link Monoid} instance formed by a <code>{@link Tuple2}&lt;_1, _2&gt;</code> and monoids over <code>_1</code> and
14+
* <code>_2</code>. Successively collapses multiple {@link Tuple2}s into a single {@link Tuple2} by collapsing the
15+
* values of each slot under the provided monoid instance.
16+
* <p>
17+
* For the {@link Semigroup}, see {@link com.jnape.palatable.lambda.semigroup.builtin.Collapse}.
18+
*
19+
* @param <_1> the first slot parameter type
20+
* @param <_2> the second slot parameter type
21+
* @see Monoid
22+
* @see Tuple2
23+
*/
24+
public final class Collapse<_1, _2> implements BiMonoidFactory<Monoid<_1>, Monoid<_2>, Tuple2<_1, _2>> {
25+
26+
private static final Collapse INSTANCE = new Collapse();
27+
28+
private Collapse() {
29+
}
30+
31+
@Override
32+
public Monoid<Tuple2<_1, _2>> apply(Monoid<_1> _1Monoid, Monoid<_2> _2Monoid) {
33+
Semigroup<Tuple2<_1, _2>> semigroup = com.jnape.palatable.lambda.semigroup.builtin.Collapse.collapse(_1Monoid, _2Monoid);
34+
return Monoid.<Tuple2<_1, _2>>monoid(semigroup, () -> tuple(_1Monoid.identity(), _2Monoid.identity()));
35+
}
36+
37+
@SuppressWarnings("unchecked")
38+
public static <_1, _2> Collapse<_1, _2> collapse() {
39+
return INSTANCE;
40+
}
41+
42+
public static <_1, _2> MonoidFactory<Monoid<_2>, Tuple2<_1, _2>> collapse(Monoid<_1> _1Monoid) {
43+
return Collapse.<_1, _2>collapse().apply(_1Monoid);
44+
}
45+
46+
public static <_1, _2> Monoid<Tuple2<_1, _2>> collapse(Monoid<_1> _1Monoid, Monoid<_2> _2Monoid) {
47+
return Collapse.<_1, _2>collapse(_1Monoid).apply(_2Monoid);
48+
}
49+
50+
public static <_1, _2> Fn1<Tuple2<_1, _2>, Tuple2<_1, _2>> collapse(Monoid<_1> _1Monoid, Monoid<_2> _2Monoid,
51+
Tuple2<_1, _2> x) {
52+
return collapse(_1Monoid, _2Monoid).apply(x);
53+
}
54+
55+
public static <_1, _2> Tuple2<_1, _2> collapse(Monoid<_1> _1Monoid, Monoid<_2> _2Monoid, Tuple2<_1, _2> x,
56+
Tuple2<_1, _2> y) {
57+
return collapse(_1Monoid, _2Monoid, x).apply(y);
58+
}
59+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.jnape.palatable.lambda.monoid.builtin;
2+
3+
import com.jnape.palatable.lambda.functions.Fn1;
4+
import com.jnape.palatable.lambda.functions.specialized.MonoidFactory;
5+
import com.jnape.palatable.lambda.monoid.Monoid;
6+
import com.jnape.palatable.lambda.semigroup.Semigroup;
7+
8+
import java.util.Collection;
9+
import java.util.function.Supplier;
10+
11+
import static com.jnape.palatable.lambda.monoid.Monoid.monoid;
12+
13+
/**
14+
* The {@link Monoid} instance formed under concatenation for an arbitrary {@link Collection}. The collection subtype
15+
* (<code>C</code>) must support {@link Collection#addAll(Collection)}.
16+
* <p>
17+
* For the {@link Semigroup}, see {@link com.jnape.palatable.lambda.semigroup.builtin.Concat}.
18+
*
19+
* @see Monoid
20+
*/
21+
public final class Concat<A, C extends Collection<A>> implements MonoidFactory<Supplier<C>, C> {
22+
23+
private static final Concat INSTANCE = new Concat();
24+
25+
private Concat() {
26+
}
27+
28+
@Override
29+
public Monoid<C> apply(Supplier<C> cSupplier) {
30+
Semigroup<C> semigroup = com.jnape.palatable.lambda.semigroup.builtin.Concat.concat();
31+
return monoid(semigroup, cSupplier);
32+
}
33+
34+
@SuppressWarnings("unchecked")
35+
public static <A, C extends Collection<A>> Concat<A, C> concat() {
36+
return INSTANCE;
37+
}
38+
39+
public static <A, C extends Collection<A>> Monoid<C> concat(Supplier<C> collectionSupplier) {
40+
return Concat.<A, C>concat().apply(collectionSupplier);
41+
}
42+
43+
public static <A, C extends Collection<A>> Fn1<C, C> concat(Supplier<C> collectionSupplier, C xs) {
44+
return concat(collectionSupplier).apply(xs);
45+
}
46+
47+
public static <A, C extends Collection<A>> C concat(Supplier<C> collectionSupplier, C xs, C ys) {
48+
return concat(collectionSupplier, xs).apply(ys);
49+
}
50+
}

0 commit comments

Comments
 (0)