CompletableFuture 是一个 Monad。但是 Applicative 在哪里?
CompletableFuture is a Monad. But where is the Applicative?
Java 的 CompletableFuture
是一个 Monad,它的方法是 thenCompose
和 thenApply
,它
对应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”到 运行。
Java 的 CompletableFuture
是一个 Monad,它的方法是 thenCompose
和 thenApply
,它
对应Haskell.
>>=
(bind)和fmap
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”到 运行。