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.