Skip to content

Commit 99339b3

Browse files
committed
Adding Monoid#foldMap; adding @see refs in javadocs for Monoid and Semigroup
1 parent de00ae9 commit 99339b3

File tree

3 files changed

+35
-0
lines changed

3 files changed

+35
-0
lines changed

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
package com.jnape.palatable.lambda.monoid;
22

3+
import com.jnape.palatable.lambda.functions.builtin.fn2.Map;
34
import com.jnape.palatable.lambda.functions.builtin.fn2.ReduceLeft;
45
import com.jnape.palatable.lambda.functions.builtin.fn2.ReduceRight;
56
import com.jnape.palatable.lambda.semigroup.Semigroup;
67

8+
import java.util.function.Function;
9+
10+
import static com.jnape.palatable.lambda.functions.builtin.fn2.Map.map;
11+
712
/**
813
* A {@link Monoid} is the pairing of a {@link Semigroup} with an identity element.
914
*
@@ -24,6 +29,7 @@ public interface Monoid<A> extends Semigroup<A> {
2429
*
2530
* @param as the elements to reduce
2631
* @return the reduction, or {@link Monoid#identity} if empty
32+
* @see ReduceLeft
2733
*/
2834
default A reduceLeft(Iterable<A> as) {
2935
return ReduceLeft.reduceLeft(toBiFunction(), as).orElse(identity());
@@ -35,11 +41,28 @@ default A reduceLeft(Iterable<A> as) {
3541
*
3642
* @param as an Iterable of elements in this monoid
3743
* @return the reduction, or {@link Monoid#identity} if empty
44+
* @see ReduceRight
3845
*/
3946
default A reduceRight(Iterable<A> as) {
4047
return ReduceRight.reduceRight(toBiFunction(), as).orElse(identity());
4148
}
4249

50+
/**
51+
* Homomorphism combined with catamorphism. Convert an <code>Iterable&lt;B&gt;</code> to an
52+
* <code>Iterable&lt;A&gt;</code> (that is, an <code>Iterable</code> of elements this monoid is formed over), then
53+
* reduce the result from left to right. Under algebraic data types, this is isomorphic to a flatMap.
54+
*
55+
* @param fn the mapping function from A to B
56+
* @param bs the Iterable of Bs
57+
* @param <B> the input Iterable element type
58+
* @return the folded result under this Monoid
59+
* @see Map
60+
* @see Monoid#reduceLeft(Iterable)
61+
*/
62+
default <B> A foldMap(Function<? super B, ? extends A> fn, Iterable<B> bs) {
63+
return reduceLeft(map(fn, bs));
64+
}
65+
4366
/**
4467
* Promote a {@link Semigroup} to a {@link Monoid} by supplying an identity element.
4568
*

src/main/java/com/jnape/palatable/lambda/semigroup/Semigroup.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public interface Semigroup<A> extends Fn2<A, A, A> {
2020
* @param a the starting accumulator
2121
* @param as the elements to fold over
2222
* @return the folded result
23+
* @see FoldLeft
2324
*/
2425
default A foldLeft(A a, Iterable<A> as) {
2526
return FoldLeft.foldLeft(toBiFunction(), a, as);
@@ -32,6 +33,7 @@ default A foldLeft(A a, Iterable<A> as) {
3233
* @param a the starting accumulator
3334
* @param as the elements to fold over
3435
* @return the folded result
36+
* @see FoldRight
3537
*/
3638
default A foldRight(A a, Iterable<A> as) {
3739
return FoldRight.foldRight(toBiFunction(), a, as);

src/test/java/com/jnape/palatable/lambda/monoid/MonoidTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
import org.junit.Test;
44

5+
import java.util.List;
6+
import java.util.Optional;
7+
58
import static com.jnape.palatable.lambda.monoid.Monoid.monoid;
69
import static java.util.Arrays.asList;
710
import static org.junit.Assert.assertEquals;
@@ -19,4 +22,11 @@ public void reduceRight() {
1922
Monoid<Integer> sum = monoid((x, y) -> x + y, 0);
2023
assertEquals((Integer) 6, sum.reduceRight(asList(1, 2, 3)));
2124
}
25+
26+
@Test
27+
public void foldMap() {
28+
Monoid<Integer> sum = monoid((x, y) -> x + y, 0);
29+
List<Optional<Integer>> optionalInts = asList(Optional.of(1), Optional.of(2), Optional.empty(), Optional.of(3), Optional.empty());
30+
assertEquals((Integer) 6, sum.foldMap(optX -> optX.orElse(0), optionalInts));
31+
}
2232
}

0 commit comments

Comments
 (0)