Monads VS期货的应用函子

时间:2016-02-01 22:46:01

标签: scala monads scalaz applicative scala-cats

假设我想聚合来自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之间使用什么来执行并行异步计算?每种方法的优缺点是什么?

1 个答案:

答案 0 :(得分:15)

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

Travis Brown有一个很好的answer

  

使用功能最弱的抽象来完成工作只是一个可靠的开发实践。原则上,这可能允许无法实现的优化,但更重要的是,它使我们编写的代码更具可重用性。

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

  

令人遗憾的是,Haskell和Scala目前使用monad工作比使用applicative functor更方便(语法等)

Kolmar指出可以拉下2个期货:

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

然而,似乎zipping more than 2 futures并不那么优雅。

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