Merge pull request #36 from kemitix/next

Next
This commit is contained in:
Paul Campbell 2018-07-12 22:21:36 +01:00 committed by GitHub
commit a9d28c9950
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 143 additions and 18 deletions

View file

@ -1,6 +1,13 @@
CHANGELOG CHANGELOG
========= =========
0.11.0
* Rename `Result.maybeThen()` as `Result.flatMapMaybe()`
* Add `Maybe.match(Consumer,Runnable)`
* Add `Maybe.isJust()`
* Add `Maybe.isNothing()`
0.10.0 0.10.0
------ ------

View file

@ -44,6 +44,16 @@ final class Just<T> implements Maybe<T> {
private final T value; private final T value;
@Override
public boolean isJust() {
return true;
}
@Override
public boolean isNothing() {
return false;
}
@Override @Override
public <R> Maybe<R> flatMap(final Function<T, Maybe<R>> f) { public <R> Maybe<R> flatMap(final Function<T, Maybe<R>> f) {
return f.apply(value); return f.apply(value);
@ -98,6 +108,11 @@ final class Just<T> implements Maybe<T> {
// ignore - not nothing // ignore - not nothing
} }
@Override
public void match(final Consumer<T> justMatcher, final Runnable nothingMatcher) {
justMatcher.accept(value);
}
@Override @Override
public void orElseThrow(final Supplier<Exception> e) { public void orElseThrow(final Supplier<Exception> e) {
// do not throw // do not throw

View file

@ -76,6 +76,20 @@ public interface Maybe<T> extends Functor<T, Maybe<?>> {
return just(value); return just(value);
} }
/**
* Checks if the Maybe is a Just.
*
* @return true if the Maybe is a Just
*/
boolean isJust();
/**
* Checks if the Maybe is Nothing.
*
* @return true if the Maybe is Nothing
*/
boolean isNothing();
/** /**
* Monad binder maps the Maybe into another Maybe using the binder method f. * Monad binder maps the Maybe into another Maybe using the binder method f.
* *
@ -149,4 +163,12 @@ public interface Maybe<T> extends Functor<T, Maybe<?>> {
* @param runnable the runnable to call if this is a Nothing * @param runnable the runnable to call if this is a Nothing
*/ */
void ifNothing(Runnable runnable); void ifNothing(Runnable runnable);
/**
* Matches the Maybe, either just or nothing, and performs either the Consumer, for Just, or Runnable for nothing.
*
* @param justMatcher the Consumer to pass the value of a Just to
* @param nothingMatcher the Runnable to call if the Maybe is a Nothing
*/
void match(Consumer<T> justMatcher, Runnable nothingMatcher);
} }

View file

@ -34,10 +34,21 @@ import java.util.stream.Stream;
* @param <T> the type of the missing content * @param <T> the type of the missing content
* @author Paul Campbell (pcampbell@kemitix.net) * @author Paul Campbell (pcampbell@kemitix.net)
*/ */
@SuppressWarnings("methodcount")
final class Nothing<T> implements Maybe<T> { final class Nothing<T> implements Maybe<T> {
static final Maybe<?> INSTANCE = new Nothing<>(); static final Maybe<?> INSTANCE = new Nothing<>();
@Override
public boolean isJust() {
return false;
}
@Override
public boolean isNothing() {
return true;
}
@Override @Override
public <R> Maybe<R> flatMap(final Function<T, Maybe<R>> f) { public <R> Maybe<R> flatMap(final Function<T, Maybe<R>> f) {
return Maybe.nothing(); return Maybe.nothing();
@ -79,6 +90,11 @@ final class Nothing<T> implements Maybe<T> {
runnable.run(); runnable.run();
} }
@Override
public void match(final Consumer<T> justMatcher, final Runnable nothingMatcher) {
nothingMatcher.run();
}
@Override @Override
public void orElseThrow(final Supplier<Exception> e) throws Exception { public void orElseThrow(final Supplier<Exception> e) throws Exception {
throw e.get(); throw e.get();

View file

@ -129,19 +129,19 @@ public interface Result<T> extends Functor<T, Result<?>> {
* @param <R> the type of the updated Result * @param <R> the type of the updated Result
* @return a new Maybe within a Result * @return a new Maybe within a Result
*/ */
static <T, R> Result<Maybe<R>> maybeThen(Result<Maybe<T>> maybeResult, Function<Maybe<T>, Result<Maybe<R>>> f) { static <T, R> Result<Maybe<R>> flatMapMaybe(Result<Maybe<T>> maybeResult, Function<Maybe<T>, Result<Maybe<R>>> f) {
return maybeResult.flatMap(f); return maybeResult.flatMap(f);
} }
/** /**
* Checks of the Result is an error. * Checks if the Result is an error.
* *
* @return true if the Result is an error. * @return true if the Result is an error.
*/ */
boolean isError(); boolean isError();
/** /**
* Checks of the Result is a success. * Checks if the Result is a success.
* *
* @return true if the Result is a success. * @return true if the Result is a success.
*/ */

View file

@ -22,7 +22,7 @@ public class MaybeTest implements WithAssertions {
@Test @Test
public void justMustBeNonNull() { public void justMustBeNonNull() {
assertThatNullPointerException().isThrownBy(() -> just(null)) assertThatNullPointerException().isThrownBy(() -> just(null))
.withMessageContaining("value"); .withMessageContaining("value");
} }
@Test @Test
@ -84,7 +84,7 @@ public class MaybeTest implements WithAssertions {
public void toOptional() { public void toOptional() {
assertThat(just(1).toOptional()).isEqualTo(Optional.of(1)); assertThat(just(1).toOptional()).isEqualTo(Optional.of(1));
assertThat(nothing() assertThat(nothing()
.toOptional()).isEqualTo(Optional.empty()); .toOptional()).isEqualTo(Optional.empty());
} }
@Test @Test
@ -194,4 +194,69 @@ public class MaybeTest implements WithAssertions {
assertThat(capture).isTrue(); assertThat(capture).isTrue();
} }
@Test
public void just_whenMatch_thenJustTriggers() {
//given
final Maybe<Integer> maybe = Maybe.just(1);
//then
maybe.match(
just -> assertThat(just).isEqualTo(1),
() -> fail("Not nothing")
);
}
@Test
public void nothing_whenMatch_thenNothingTriggers() {
//given
final Maybe<Integer> maybe = Maybe.nothing();
final AtomicBoolean flag = new AtomicBoolean(false);
//when
maybe.match(
just -> fail("Not a just"),
() -> flag.set(true)
);
//then
assertThat(flag).isTrue();
}
@Test
public void just_isJust_isTrue() {
//given
final Maybe<Integer> maybe = just(1);
//when
final boolean isJust = maybe.isJust();
//then
assertThat(isJust).isTrue();
}
@Test
public void just_isNothing_isFalse() {
//given
final Maybe<Integer> maybe = just(1);
//when
final boolean isNothing = maybe.isNothing();
//then
assertThat(isNothing).isFalse();
}
@Test
public void nothing_isJust_isFalse() {
//given
final Maybe<Object> maybe = nothing();
//when
final boolean isJust = maybe.isJust();
//then
assertThat(isJust).isFalse();
}
@Test
public void nothing_isNothing_isTrue() {
//given
final Maybe<Object> maybe = nothing();
//when
final boolean isNothing = maybe.isNothing();
//then
assertThat(isNothing).isTrue();
}
} }

View file

@ -605,24 +605,24 @@ public class ResultTest implements WithAssertions {
} }
@Test @Test
public void okayJust_whenMaybeThen_whereOkayJust_thenIsOkayJust() { public void okayJust_whenFlatMapMaybe_whereOkayJust_thenIsOkayJust() {
//given //given
final Result<Maybe<Integer>> okJust = Result.ok(Maybe.just(1)); final Result<Maybe<Integer>> okJust = Result.ok(Maybe.just(1));
//when //when
final Result<Maybe<Integer>> result = Result.maybeThen(okJust, mv -> Result.ok(Maybe.just(2))); final Result<Maybe<String>> result = Result.flatMapMaybe(okJust, maybe -> Result.ok(maybe.flatMap(v -> Maybe.just("2"))));
//then //then
result.match( result.match(
success -> assertThat(success.toOptional()).contains(2), success -> assertThat(success.toOptional()).contains("2"),
error -> fail("Not an error") error -> fail("Not an error")
); );
} }
@Test @Test
public void okayJust_whenMaybeThen_whereOkayNothing_thenIsOkayNothing() { public void okayJust_whenFlatMapMaybe_whereOkayNothing_thenIsOkayNothing() {
//given //given
final Result<Maybe<Integer>> okJust = Result.ok(Maybe.just(1)); final Result<Maybe<Integer>> okJust = Result.ok(Maybe.just(1));
//when //when
final Result<Maybe<Integer>> result = Result.maybeThen(okJust, v -> Result.ok(Maybe.nothing())); final Result<Maybe<String>> result = Result.flatMapMaybe(okJust, maybe -> Result.ok(maybe.flatMap(v -> Maybe.nothing())));
//then //then
result.match( result.match(
success -> assertThat(success.toOptional()).isEmpty(), success -> assertThat(success.toOptional()).isEmpty(),
@ -631,12 +631,12 @@ public class ResultTest implements WithAssertions {
} }
@Test @Test
public void okayJust_whenMaybeThen_whereError_thenIsError() { public void okayJust_whenFlatMapMaybe_whereError_thenIsError() {
//given //given
final Result<Maybe<Integer>> okJust = Result.ok(Maybe.just(1)); final Result<Maybe<Integer>> okJust = Result.ok(Maybe.just(1));
final RuntimeException exception = new RuntimeException(); final RuntimeException exception = new RuntimeException();
//when //when
final Result<Maybe<Integer>> result = Result.maybeThen(okJust, v -> Result.error(exception)); final Result<Maybe<Integer>> result = Result.flatMapMaybe(okJust, v -> Result.error(exception));
//then //then
result.match( result.match(
success -> fail("Not a success"), success -> fail("Not a success"),
@ -645,27 +645,27 @@ public class ResultTest implements WithAssertions {
} }
@Test @Test
public void okayNothing_whenMaybeThen_thenDoNotApply() { public void okayNothing_whenFlatMapMaybe_thenDoNotApply() {
//given //given
final Result<Maybe<Integer>> okNothing = Result.ok(Maybe.nothing()); final Result<Maybe<Integer>> okNothing = Result.ok(Maybe.nothing());
//when //when
final Result<Maybe<Integer>> result = Result.maybeThen(okNothing, v -> Result.ok(Maybe.just(2))); final Result<Maybe<String>> result = Result.flatMapMaybe(okNothing, maybe -> Result.ok(maybe.flatMap(v -> Maybe.just("2"))));
//then //then
okNothing.match( result.match(
success -> assertThat(success.toOptional()).isEmpty(), success -> assertThat(success.toOptional()).isEmpty(),
error -> fail("Not an error") error -> fail("Not an error")
); );
} }
@Test @Test
public void error_whenMaybeThen_thenDoNotApply() { public void error_whenFlatMapMaybe_thenDoNotApply() {
//given //given
final RuntimeException exception = new RuntimeException(); final RuntimeException exception = new RuntimeException();
final Result<Maybe<Integer>> maybeResult = Result.error(exception); final Result<Maybe<Integer>> maybeResult = Result.error(exception);
//when //when
final Result<Maybe<Integer>> result = Result.maybeThen(maybeResult, v -> Result.ok(Maybe.just(2))); final Result<Maybe<String>> result = Result.flatMapMaybe(maybeResult, maybe -> Result.ok(maybe.flatMap(v -> Maybe.just("2"))));
//then //then
maybeResult.match( result.match(
success -> fail("Not a success"), success -> fail("Not a success"),
error -> assertThat(error).isSameAs(exception) error -> assertThat(error).isSameAs(exception)
); );