Add Reader.map and Reader.andThen methods (#227)
This commit is contained in:
parent
33869a7c26
commit
5b09c1b525
2 changed files with 72 additions and 0 deletions
|
@ -2,6 +2,9 @@ package net.kemitix.mon.reader;
|
|||
|
||||
import org.apiguardian.api.API;
|
||||
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Returns a program ready to run upon the supply of a suitable environment.
|
||||
*
|
||||
|
@ -20,4 +23,28 @@ public interface Reader<E, R> {
|
|||
*/
|
||||
R run(E env);
|
||||
|
||||
/**
|
||||
* Applies the function provided to the reader when it is run.
|
||||
*
|
||||
* @param f the function, which takes an {@link E} as its only parameter
|
||||
* @param <V> the type of the functions output
|
||||
* @return a new Reader to provide the result of the supplied function
|
||||
*/
|
||||
@API(status = API.Status.EXPERIMENTAL)
|
||||
default <V> Reader<E, V> map(Function<R, V> f) {
|
||||
return e -> f.apply(run(e));
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the function provided to the reader when it is run.
|
||||
*
|
||||
* @param f the function, which takes an {@link E} and the previously
|
||||
* generated value as its two parameters
|
||||
* @param <V> the type of the functions output
|
||||
* @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) {
|
||||
return env -> f.apply(env, run(env));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ import org.assertj.core.api.WithAssertions;
|
|||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class ReaderTest
|
||||
implements WithAssertions {
|
||||
|
||||
|
@ -30,6 +32,49 @@ public class ReaderTest
|
|||
assertThat(result).isEqualTo(value);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("map")
|
||||
void map() {
|
||||
//given
|
||||
AtomicInteger value = new AtomicInteger(123);
|
||||
Environment env = new Environment() {
|
||||
@Override
|
||||
public Integer intValue() {
|
||||
return value.incrementAndGet();
|
||||
}
|
||||
};
|
||||
Reader<Environment, String> program =
|
||||
((Reader<Environment, Integer>) e -> e.intValue())
|
||||
.map(i -> i * 2)
|
||||
.map(i -> Integer.toString(i));
|
||||
//when
|
||||
String result = program.run(env);
|
||||
//then
|
||||
assertThat(result).isEqualTo("248");// (123 + 1) * 2
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("andThen")
|
||||
void andThen() {
|
||||
//given
|
||||
AtomicInteger value = new AtomicInteger(123);
|
||||
Environment env = new Environment() {
|
||||
@Override
|
||||
public Integer intValue() {
|
||||
return value.incrementAndGet();
|
||||
}
|
||||
};
|
||||
Reader<Environment, String> program =
|
||||
((Reader<Environment, Integer>) e -> e.intValue())
|
||||
.andThen((e, i) -> e.intValue() + (i * 2))
|
||||
.andThen((e, i) -> String.format("%.2f",
|
||||
i.floatValue() / e.intValue()));
|
||||
//when
|
||||
String result = program.run(env);
|
||||
//then
|
||||
assertThat(result).isEqualTo("2.96");// ((123 * 2) + (123 + 1)) / (123 + 2)
|
||||
}
|
||||
|
||||
private interface Environment {
|
||||
|
||||
Integer intValue();
|
||||
|
|
Loading…
Reference in a new issue