CompletableFuture 是一个 Monad。但是 Applicative 在哪里?

CompletableFuture is a Monad. But where is the Applicative?

Java 的 CompletableFuture 是一个 Monad,它的方法是 thenComposethenApply,它 对应Haskell.

中的>>=(bind)和fmap

任何 Monad 都可以产生 Applicative。现在CompletableFuture是否有对应Haskell中的<*>(ap)的方法,还是可以根据现有的方法实现这样的功能?

CompletableFuture没有直接对应Haskell中的<*>的方法。但是它可以通过 翻译相应的 Haskell 代码以将 Monad 转换为 Applicative:

(<*>) :: Monad f => f (a -> b) -> f a -> f b
(<*>) f a = f >>= (`fmap`a )

为了适应 Java 的术语,让我们在 Java 中调用此函数 alsoApply:

static <T, R> CompletableFuture<R> alsoApply(CompletableFuture<T> future, CompletableFuture<Function<T, R>> f) {
    return f.thenCompose(future::thenApply);
}

有了这个我们现在可以做到

CompletableFuture<String> future = alsoApply(
    CompletableFuture.supplyAsync(() -> "a"),
    CompletableFuture.supplyAsync(() -> "b")
.thenApply(b -> a -> a + b));

assertEquals("ab", future.get());

,这导致两个 futures 分别在不同线程上并行返回“a”和“b”到 运行。