diff --git a/README.md b/README.md index fc539ca..3c60ed3 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ https://oss.sonatype.org/content/repositories/releases/net/kemitix/mon/) https://img.shields.io/maven-central/v/net.kemitix/mon.svg?style=for-the-badge)]( https://search.maven.org/artifact/net.kemitix/mon) +The documentation below is being slowly migrated to [Javadoc](https://kemitix.github.io/mon/). + - [Maven Usage](#Maven-Usage) - [Wrapper](#Wrapper) - light-weight type-alias-like - [TypeAlias](#TypeAlias) - type-alias-like monadic wrapper diff --git a/pom.xml b/pom.xml index e5857a4..ad2f0fe 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ mon - 3.2.0 + 3.3.0 Mon Wrapper, TypeAlias, Maybe, Result, Tree, Lazy, Either and Combinators for Java. diff --git a/src/main/java/net/kemitix/mon/reader/Reader.java b/src/main/java/net/kemitix/mon/reader/Reader.java index 4ae091b..c54f2ae 100644 --- a/src/main/java/net/kemitix/mon/reader/Reader.java +++ b/src/main/java/net/kemitix/mon/reader/Reader.java @@ -44,7 +44,21 @@ public interface Reader { * @return a new Reader to provided the result of the supplied function */ @API(status = API.Status.EXPERIMENTAL) - default Reader andThen(BiFunction f) { + default Reader flatMap(BiFunction f) { return env -> f.apply(env, run(env)); } + + /** + * Applies the function provided to the reader when run, and executes that + * resulting reader. + * + * @param f the function which takes the previously generated value and + * produces another Reader + * @param the type of the value the new Reader returns + * @return a new Reader + */ + @API(status = API.Status.EXPERIMENTAL) + default Reader flatMap(Function> f) { + return env -> f.apply(run(env)).run(env); + } } diff --git a/src/test/java/net/kemitix/mon/ReaderTest.java b/src/test/java/net/kemitix/mon/ReaderTest.java index 5313dd0..14dd0ea 100644 --- a/src/test/java/net/kemitix/mon/ReaderTest.java +++ b/src/test/java/net/kemitix/mon/ReaderTest.java @@ -6,6 +6,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Function; public class ReaderTest implements WithAssertions { @@ -66,8 +67,8 @@ public class ReaderTest }; Reader program = ((Reader) e -> e.intValue()) - .andThen((e, i) -> e.intValue() + (i * 2)) - .andThen((e, i) -> String.format("%.2f", + .flatMap((e, i) -> e.intValue() + (i * 2)) + .flatMap((e, i) -> String.format("%.2f", i.floatValue() / e.intValue())); //when String result = program.run(env); @@ -75,6 +76,32 @@ public class ReaderTest assertThat(result).isEqualTo("2.96");// ((123 * 2) + (123 + 1)) / (123 + 2) } + @Test + @DisplayName("flatMap") + void flatMap() { + //given + AtomicInteger value = new AtomicInteger(123); + Environment env = new Environment() { + @Override + public Integer intValue() { + return value.incrementAndGet(); + } + }; + Function> addNextValue = + integer -> (Reader) e -> e.intValue() + integer; + Function> divideByNextValue = + integer -> (Reader) e -> integer.floatValue() / e.intValue(); + Reader program = + ((Reader) e -> e.intValue()) + .flatMap(addNextValue) + .flatMap(divideByNextValue) + .map(f -> String.format("%.3f", f)); + //when + String result = program.run(env); + //then + assertThat(result).isEqualTo("1.976");// (123 + 124) / 125 + } + private interface Environment { Integer intValue();