Scala 中的 List[Try[T]] 到 Try[List[T]]
List[Try[T]] to Try[List[T]] in Scala
我想知道如何在 Scala 中将 List[Try[T]]
转换为 Try[List[T]]
?
我尝试过使用累加器并向右折叠,但似乎不太理想。
使用猫就像:
import cats._
import cats.data._
import cats.implicits._
import scala.util.{Try, Success, Failure}
val tries: List[Try[Int]] = List(Success(1), Success(2), Success(3))
tries.sequence
Traverse docs 中的更多信息。
我还建议只使用 Cats...
但是,如果您不想为您的项目添加另一个 (大) 依赖项,那么只需要一个功能即可。
你可以自己实现它! - (cats 实现可能更好)
import scala.util.{Try, Success, Failure}
def sequence[A](list: List[Try[A]]): Try[List[A]] = {
@annotation.tailrec
def loop(remaining: List[Try[A]], acc: List[A]): Try[List[A]] =
remaining match {
case Nil => Success(acc.reverse)
case Success(a) :: tail => loop(remaining = tail, acc = a :: acc)
case Failure(e) :: _ => Failure(e)
}
loop(remaining = list, acc = List.empty)
}
另外,如果你之前做了 map
,你可以使用 traverse
而不是 sequence
。
def traverse[A, B](list: List[A])(f: A => Try[B]): Try[List[B]] = {
@annotation.tailrec
def loop(remaining: List[A], acc: List[B]): Try[List[B]] =
remaining match {
case Nil => Success(acc.reverse)
case head :: tail => f(head) match {
case Success(b) => loop(remaining = tail, acc = b :: acc)
case Failure(e) => Failure(e)
}
}
loop(remaining = list, acc = List.empty)
}
无论如何,Cats(以及一般的 FP) 非常有用(如您所见).
因此,我建议您尝试一下。
Cats 是一种不错的方式,但它可以通过标准库完成,不会太复杂。
import util.{Try, Success, Failure}
def seqnc[T](lst :List[Try[T]]) :Try[List[T]] =
lst.foldRight(Try(List.empty[T])) {
case (tt, acc) => for { t <- tt
a <- acc
} yield t :: a
}
Try(list.map(_.get))
这将 return 只有第一个失败,所以如果你想捕获列表中的所有失败,你需要更复杂的东西。
我想知道如何在 Scala 中将 List[Try[T]]
转换为 Try[List[T]]
?
我尝试过使用累加器并向右折叠,但似乎不太理想。
使用猫就像:
import cats._
import cats.data._
import cats.implicits._
import scala.util.{Try, Success, Failure}
val tries: List[Try[Int]] = List(Success(1), Success(2), Success(3))
tries.sequence
Traverse docs 中的更多信息。
我还建议只使用 Cats...
但是,如果您不想为您的项目添加另一个 (大) 依赖项,那么只需要一个功能即可。
你可以自己实现它! - (cats 实现可能更好)
import scala.util.{Try, Success, Failure}
def sequence[A](list: List[Try[A]]): Try[List[A]] = {
@annotation.tailrec
def loop(remaining: List[Try[A]], acc: List[A]): Try[List[A]] =
remaining match {
case Nil => Success(acc.reverse)
case Success(a) :: tail => loop(remaining = tail, acc = a :: acc)
case Failure(e) :: _ => Failure(e)
}
loop(remaining = list, acc = List.empty)
}
另外,如果你之前做了 map
,你可以使用 traverse
而不是 sequence
。
def traverse[A, B](list: List[A])(f: A => Try[B]): Try[List[B]] = {
@annotation.tailrec
def loop(remaining: List[A], acc: List[B]): Try[List[B]] =
remaining match {
case Nil => Success(acc.reverse)
case head :: tail => f(head) match {
case Success(b) => loop(remaining = tail, acc = b :: acc)
case Failure(e) => Failure(e)
}
}
loop(remaining = list, acc = List.empty)
}
无论如何,Cats(以及一般的 FP) 非常有用(如您所见).
因此,我建议您尝试一下。
Cats 是一种不错的方式,但它可以通过标准库完成,不会太复杂。
import util.{Try, Success, Failure}
def seqnc[T](lst :List[Try[T]]) :Try[List[T]] =
lst.foldRight(Try(List.empty[T])) {
case (tt, acc) => for { t <- tt
a <- acc
} yield t :: a
}
Try(list.map(_.get))
这将 return 只有第一个失败,所以如果你想捕获列表中的所有失败,你需要更复杂的东西。