使用返回 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

我不确定为什么删除了另一个答案 - 但对于普通的 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)))

我错过了什么吗?

尝试从

猫那里foldM

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)

不使用外部库:

实施"特殊"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)

最新更新