Ну ... nicest 'Scala way'
зависит от того, что ваши требования?
Итак ... вы следующие 3 def
с,
def getElements1(id: Guid): Try[Seq[SE]]
def getElements2(id: Guid): Try[Seq[SE]]
def getElements3(id: Guid): Try[Seq[SE]]
Случай 1 - Результат терпит неудачу, если по крайней мере один из них не удается, и вы получите ошибку только один отказ.
val result: Try[Seq[SE]] = for {
emements1 <- getElements1(id)
emements2 <- getElements2(id)
emements3 <- getElements3(id)
} yield emements1 ++ emements2 ++ emements3
Случай 2 - Результат терпит неудачу, если по крайней мере один из них не удается, и вы хотите, чтобы получить ошибку только все неудачи,
def trySeqToEither[T](tryTSeq: Seq[Try[T]]): Either[Seq[Throwable], Seq[T]] = {
val accInit: Either[Seq[Throwable], Seq[T]] = Right(Seq.empty[T])
tryTSeq.aggregate(accInit)({
case (Right(seq), Success(t)) => Right(seq :+ t)
case (Right(seq), Failure(ex)) => Left(Seq[Throwable](ex))
case (Left(seq), Success(t)) => Left(seq)
case (Left(seq), Failure(ex)) => Left(seq :+ ex)
})
}
val seqResultEither: Either[Seq[Throwable], Seq[Seq[SE]]] = trySeqToEither(
Seq(getElements1(id), getElements2(id), getElements3(id))
)
val resultEither: Either[Seq[Throwable], Seq[SE]] = seqResultEither match {
case Right(seqResult) => Right(seqResult.flatten)
case Left(seqThrowable) => Left(seqThrowable)
}
Случай 3 - Результат игнорирует неисправные вычисления
val emementsOption1 = getElements1(id).toOption
val emementsOption1 = getElements2(id).toOption
val emementsOption3 = getElements3(id).toOption
val result: Seq[SE] = Seq[Seq[SE]](emementsOption1, emementsOption2, emementsOption3).flatten