> f);
+
+ /**
+ * Reduce two Results of the same type into one using the reducing function provided.
+ *
+ * If either Result is an error, then the reduce will return the error. If both are errors, then the error of
+ * {@link this} Result will be returned.
+ *
+ * @param identify the identify Result
+ * @param operator the function to combine the values the Results
+ * @return a Result containing the combination of the two Results
+ */
+ Result reduce(Result identify, BinaryOperator operator);
}
diff --git a/src/main/java/net/kemitix/mon/result/Success.java b/src/main/java/net/kemitix/mon/result/Success.java
index b7d0ef3..4c91623 100644
--- a/src/main/java/net/kemitix/mon/result/Success.java
+++ b/src/main/java/net/kemitix/mon/result/Success.java
@@ -26,6 +26,7 @@ import net.kemitix.mon.maybe.Maybe;
import java.util.Objects;
import java.util.concurrent.Callable;
+import java.util.function.BinaryOperator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -51,11 +52,6 @@ class Success implements Result {
return true;
}
- @Override
- public Result flatMap(final Function> f) {
- return f.apply(value);
- }
-
@Override
public Result map(final Function f) {
return Result.ok(f.apply(value));
@@ -105,6 +101,16 @@ class Success implements Result {
return f.apply(value).call(this);
}
+ @Override
+ public Result reduce(final Result identity, final BinaryOperator operator) {
+ return flatMap(a -> identity.flatMap(b -> Result.of(() -> operator.apply(a, b))));
+ }
+
+ @Override
+ public Result flatMap(final Function> f) {
+ return f.apply(value);
+ }
+
@Override
public boolean equals(final Object other) {
return other instanceof Success && Objects.equals(value, ((Success) other).value);
diff --git a/src/test/java/net/kemitix/mon/ResultTest.java b/src/test/java/net/kemitix/mon/ResultTest.java
index edda0e3..3805a24 100644
--- a/src/test/java/net/kemitix/mon/ResultTest.java
+++ b/src/test/java/net/kemitix/mon/ResultTest.java
@@ -300,7 +300,7 @@ public class ResultTest implements WithAssertions {
//given
final Maybe> justSuccess = Maybe.just(Result.ok(1));
//when
- final Result> result = Result.invert(justSuccess);
+ final Result> result = Result.swap(justSuccess);
//then
result.match(
success -> assertThat(success.toOptional()).contains(1),
@@ -314,7 +314,7 @@ public class ResultTest implements WithAssertions {
final RuntimeException exception = new RuntimeException();
final Maybe> justError = Maybe.just(Result.error(exception));
//when
- final Result> result = Result.invert(justError);
+ final Result> result = Result.swap(justError);
//then
result.match(
success -> fail("Not a success"),
@@ -327,7 +327,7 @@ public class ResultTest implements WithAssertions {
//given
final Maybe> nothing = Maybe.nothing();
//when
- final Result> result = Result.invert(nothing);
+ final Result> result = Result.swap(nothing);
//then
result.match(
success -> assertThat(success.toOptional()).isEmpty(),
@@ -671,6 +671,66 @@ public class ResultTest implements WithAssertions {
);
}
+ @Test
+ public void okayOkay_whenReduce_thenCombine() {
+ //given
+ final Result result1 = Result.ok(1);
+ final Result result10 = Result.ok(10);
+ //when
+ final Result result11 = result1.reduce(result10, (a, b) -> a + b);
+ //then
+ result11.match(
+ success -> assertThat(success).isEqualTo(11),
+ error -> fail("Not an error")
+ );
+ }
+
+ @Test
+ public void okayError_whenReduce_thenError() {
+ //given
+ final Result result1 = Result.ok(1);
+ final RuntimeException exception = new RuntimeException();
+ final Result result10 = Result.error(exception);
+ //when
+ final Result result11 = result1.reduce(result10, (a, b) -> a + b);
+ //then
+ result11.match(
+ success -> fail("Not a success"),
+ error -> assertThat(error).isSameAs(exception)
+ );
+ }
+
+ @Test
+ public void errorOkay_whenReduce_thenError() {
+ //given
+ final RuntimeException exception = new RuntimeException();
+ final Result result1 = Result.error(exception);
+ final Result result10 = Result.ok(10);
+ //when
+ final Result result11 = result1.reduce(result10, (a, b) -> a + b);
+ //then
+ result11.match(
+ success -> fail("Not a success"),
+ error -> assertThat(error).isSameAs(exception)
+ );
+ }
+
+ @Test
+ public void errorError_whenReduce_thenError() {
+ //given
+ final RuntimeException exception1 = new RuntimeException();
+ final Result result1 = Result.error(exception1);
+ final RuntimeException exception10 = new RuntimeException();
+ final Result result10 = Result.error(exception10);
+ //when
+ final Result result11 = result1.reduce(result10, (a, b) -> a + b);
+ //then
+ result11.match(
+ success -> fail("Not a success"),
+ error -> assertThat(error).isSameAs(exception1)
+ );
+ }
+
@RequiredArgsConstructor
private static class UseCase {