Add Reader.flatMap() (#228)

* Add link to online Javadoc.

* Add Reader.flatMap
This commit is contained in:
Paul Campbell 2021-08-20 07:37:28 +01:00 committed by GitHub
parent 5b09c1b525
commit 58796c8f73
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 47 additions and 4 deletions

View file

@ -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

View file

@ -11,7 +11,7 @@
</parent>
<artifactId>mon</artifactId>
<version>3.2.0</version>
<version>3.3.0</version>
<name>Mon</name>
<description>Wrapper, TypeAlias, Maybe, Result, Tree, Lazy, Either and Combinators for Java.

View file

@ -44,7 +44,21 @@ public interface Reader<E, R> {
* @return a new Reader to provided the result of the supplied function
*/
@API(status = API.Status.EXPERIMENTAL)
default <V> Reader<E, V> andThen(BiFunction<E, R, V> f) {
default <V> Reader<E, V> flatMap(BiFunction<E, R, V> 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 <V> the type of the value the new Reader returns
* @return a new Reader
*/
@API(status = API.Status.EXPERIMENTAL)
default <V> Reader<E, V> flatMap(Function<R, Reader<E, V>> f) {
return env -> f.apply(run(env)).run(env);
}
}

View file

@ -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<Environment, String> program =
((Reader<Environment, Integer>) 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<Integer, Reader<Environment, Integer>> addNextValue =
integer -> (Reader<Environment, Integer>) e -> e.intValue() + integer;
Function<Integer, Reader<Environment, Float>> divideByNextValue =
integer -> (Reader<Environment, Float>) e -> integer.floatValue() / e.intValue();
Reader<Environment, String> program =
((Reader<Environment, Integer>) 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();