繁体   English   中英

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 文档中的更多信息。

Try(list.map(_.get))

这将只返回第一个失败,所以如果你想捕获列表中的所有失败,你需要更复杂的东西。

我还建议只使用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
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM