CompletableFuture is a Monad. But where is the Applicative?
Java's CompletableFuture
is a Monad given its methods thenCompose
and thenApply
, which
correspond to >>=
(bind) and fmap
in Haskell.
It is a well known fact that any Monad gives rise to an Applicative. Now, does CompletableFuture
have a method that corresponds to <*>
(ap) in Haskell or can such a function be implemented in terms of the existing methods?
Solution 1:
CompletableFuture
does not have a method that directly corresponds to <*>
in Haskell. However it can be derived by
translating the corresponding Haskell code for turning a Monad into an Applicative:
(<*>) :: Monad f => f (a -> b) -> f a -> f b
(<*>) f a = f >>= (`fmap`a )
In adaption of Java's terminology, let's call this function alsoApply
in Java:
static <T, R> CompletableFuture<R> alsoApply(CompletableFuture<T> future, CompletableFuture<Function<T, R>> f) {
return f.thenCompose(future::thenApply);
}
With this we can now do
CompletableFuture<String> future = alsoApply(
CompletableFuture.supplyAsync(() -> "a"),
CompletableFuture.supplyAsync(() -> "b")
.thenApply(b -> a -> a + b));
assertEquals("ab", future.get());
, which causes the two futures returning "a" and "b" respectively to run in parallel on different threads.