使用 returns Future 的二进制操作折叠序列

Folding a sequence with a binary operation that returns Future

假设我有一个函数 op: (Int, Int) => Future[Int] 并且需要编写一个新函数 foo :

def foo(xs: Seq[Int], 
        zero: Int, 
        op: (Int, Int) => Future[Int]): Future[Int] = ???

foo 应作为 foldLeft 并按顺序将 op 应用于 xs 中的所有元素,例如:

val op: (Int, Int) => Future[Int] = (x, y) => Future(x + y)
val xs = (1 to 10)
val fut = foo(xs, 0, op) // should return Future of 55
fut.value // Some(Success(55))

您将如何实施 foo

尝试 来自猫:

import cats._
import cats.implicits._

def foo(xs: Seq[Int], zero: Int, op: (Int, Int) => Future[Int]): Future[Int] =
  Foldable[List].foldM(xs.toList, zero)(op)

我不确定为什么其他答案被删除了 - 但使用 plain Scala 这对我有用:

 def foo(xs: Seq[Int], zero: Int, op: (Int, Int) => Future[Int]): Future[Int] =  

    xs.foldLeft(Future.successful(zero))((a, b) => a.flatMap(op(_, b)))

我是不是漏掉了什么?

不使用外部库:

实施 "special" foldLeft:

def foldLeft[Int](xs: Seq[Int], z: Int)(op: (Int, Int) => Future[Int]): Future[Int] = {
 def f(xs: Seq[Int], accF: Future[Int]): Future[Int] = xs match {
   case Seq()   => accF
   case x +: xs => accF.flatMap(acc => f(xs, op(acc, x)))
 }

 f(xs, Future.successful(z))

}

并使用它:

def foo(xs: Seq[Int], 
    zero: Int, 
    op: (Int, Int) => Future[Int]): Future[Int] = foldLeft(xs, zero)(op)