Monads VS Futures 的应用函子

Monads VS Applicative functors for Futures

假设我想聚合来自 2 个远程服务的数据,并尽可能快地提供响应:

def loadUser: Future[User]
def loadData: Future[Data]

case class Payload(user: User, data: Data)

我了解到这个是顺序执行异步任务的:

for {
  user <- loadUser
  data <- loadData
} yield Payload(user,data)

虽然这个并行执行它们,因为异步任务在顺序链接之前被触发:

val userF = loadUser
val dataF = loadData
for {
  user <- userF 
  data <- dataF
} yield Payload(user,data)

然而,这种差异对我来说有点过于含蓄,有些人一开始可能没有注意到。


应用程序也解决了这个工作

(loadUser |@| loadData) { Payload(_,_) }

有人能告诉我我更愿意在应用程序和 monad 之间使用什么来执行并行异步计算吗?每种方法的优缺点是什么?

所以,我正在回答我自己的问题,因为所有评论 link 都是有用的资源。

Travis Brown 表现不错 answer:

it's just a solid development practice to use the least powerful abstraction that will get the job done. In principle this may allow optimizations that wouldn't otherwise be possible, but more importantly it makes the code we write more reusable.

他还指出了一个有趣的事实:

It's a shame that both Haskell and Scala currently make working with monads so much more convenient (syntactically, etc.) than working with applicative functors

Kolmar 指出可以压缩 2 个期货:

for ((user, data) <- loadUser zip loadData) yield Payload(user, data)

不过好像zipping more than 2 futures不太优雅

所以似乎 Applicative functor 最适合这项工作,但与 monad 相比,Scala 标准库并不鼓励我们使用它们,你需要一个额外的库,如 Scalaz 或 Cats