Scala - Свести последовательность EitherT - PullRequest
0 голосов
/ 01 сентября 2018

Предположим, у меня есть следующее:

val ints: Seq[Int] = ???
def foo(i: Int): EitherT[Future, Error, Seq[String]] = ???

Я хочу вызвать foo с ints и накапливать Seq[String] результат, чтобы в итоге вернуть EitherT[Future, Error, Seq[String]].

ints.map(i => foo(i))

Очевидно, что вышеприведенное возвращает Seq[EitherT[Future, Error, Seq[String]]], и это не я хочу. Когда foo возвращает Error в первый раз в map, я хочу прекратить обход и вернуть ошибку.

Как правильно достичь моей цели?

1 Ответ

0 голосов
/ 01 сентября 2018
ints.map(foo).reduce(for { a <- _ ; b <- _ } yield a ++ b)

Это в основном то, что вы хотите, но я не думаю, что это точно соответствует требованиям для этого предложения:

Когда foo возвращает Error впервые на карте, я хочу прекратить обход и вернуть ошибку.

Проблема в том, что вам нужно пройти через seq до завершения любого из фьючерсов, поэтому вы не знаете, возвращают ли они ошибки еще. Вы можете «заблокировать» один за другим и не делать следующий вызов foo до тех пор, пока предыдущий не завершится, но тогда вы не получите никакого параллелизма. Теоретически возможно запустить все эти фьючерсы, а затем отменить все еще работающие, когда возвращается ошибка, но, к сожалению, отмена фьючерса - это не то, что естественно легко.

...