Skip to content

Instantly share code, notes, and snippets.

@vjames19
Created October 26, 2017 17:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vjames19/e968117cc068ddabdb25c2f3f0684609 to your computer and use it in GitHub Desktop.
Save vjames19/e968117cc068ddabdb25c2f3f0684609 to your computer and use it in GitHub Desktop.
Java Future Optional Monad
package com.github.vjames19.functional;
import lombok.RequiredArgsConstructor;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import static java.util.concurrent.CompletableFuture.completedFuture;
@RequiredArgsConstructor
public class FutureOptional<T> {
private static final FutureOptional EMPTY = futureOptional(Optional.empty());
private final CompletableFuture<Optional<T>> future;
public static <T> FutureOptional<T> futureOptional(Optional<T> optional) {
return new FutureOptional<>(completedFuture(optional));
}
public static <T> FutureOptional<T> futureOptionalPresent(CompletableFuture<T> future) {
return new FutureOptional<>(future.thenApply(Optional::ofNullable));
}
public static <T> FutureOptional<T> futureOptional(CompletableFuture<Optional<T>> future) {
return new FutureOptional<>(future);
}
@SuppressWarnings("unchecked")
public static <T> FutureOptional<T> empty() {
return (FutureOptional<T>) EMPTY;
}
public <R> FutureOptional<R> map(Function<T, R> f) {
return futureOptional(future.thenApply(optional -> optional.map(f)));
}
public <R> FutureOptional<R> flatMap(Function<T, FutureOptional<R>> f) {
final CompletableFuture<Optional<R>> fu = future.thenCompose(optional -> optional
.map(value -> f.apply(value).future)
.orElse(completedFuture(Optional.empty())));
return futureOptional(fu);
}
public CompletableFuture<Optional<T>> future() {
return future;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment