Складывание последовательности с помощью двоичной операции, которая возвращает Future - PullRequest
5 голосов
/ 19 июня 2019

Предположим, у меня есть функция 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?

Ответы [ 3 ]

6 голосов
/ 19 июня 2019

Я не уверен, почему был удален другой ответ - но с 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)))

Я что-то пропустил?

5 голосов
/ 19 июня 2019

Попробуйте 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)
2 голосов
/ 19 июня 2019

Без использования внешней библиотеки:

Реализация «специального» * ​​1003 *:

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)
...