Add Reader.map and Reader.andThen methods (#227)

This commit is contained in:
Paul Campbell 2021-08-19 13:46:22 +01:00 committed by GitHub
parent 33869a7c26
commit 5b09c1b525
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 72 additions and 0 deletions

View file

@ -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));
}
}

View file

@ -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();