Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何将Seq[Try]转换为Try[Seq]_Scala - Fatal编程技术网

Scala 如何将Seq[Try]转换为Try[Seq]

Scala 如何将Seq[Try]转换为Try[Seq],scala,Scala,有了期货就有了一种将Seq[Future]转换为Future[Seq]的简便方法: Future.序列(seqOfFutures) 我找不到带有Try的模拟对象 它与foldLeft一起工作,但我真正喜欢的是Try.sequence(seqOfTry) 是否有理由不提供此类功能 如何正确地做到这一点 语义: 成功值列表:Success(Seq(1,2,3,4)) 对于故障,有两种可能性: 第一次失败Failure并返回它。这是通过以下问题来解决的: 收集所有故障并返回“复合”故障 是否还有一

有了
期货
就有了一种将
Seq[Future]
转换为
Future[Seq]
的简便方法:

Future.序列(seqOfFutures)

我找不到带有
Try
的模拟对象

它与
foldLeft
一起工作,但我真正喜欢的是
Try.sequence(seqOfTry)

是否有理由不提供此类功能

如何正确地做到这一点

语义:

成功值列表:
Success(Seq(1,2,3,4))

对于故障,有两种可能性:

  • 第一次失败
    Failure
    并返回它。这是通过以下问题来解决的:

  • 收集所有
    故障
    并返回“复合”故障


是否还有一个解决方案“强”“复合”失效< /强>

< P>按照路易斯的建议<代码>验证< /COD>是为错误积累而设计的,所以考虑类似于

哪个输出

res2: cats.data.ValidatedNec[Throwable,List[Int]] = Invalid(Chain(java.lang.RuntimeException: boom, java.lang.RuntimeException: crash))
res3: cats.data.ValidatedNec[Throwable,List[Int]] = Valid(List(1, 2, 3))
res0: scala.util.Try[List[Int]] = Failure(java.lang.RuntimeException: boom)
在哪里


如果没有误差累积,我们就可以这样排序

import cats.implicits._
la.sequence 
哪个输出

res2: cats.data.ValidatedNec[Throwable,List[Int]] = Invalid(Chain(java.lang.RuntimeException: boom, java.lang.RuntimeException: crash))
res3: cats.data.ValidatedNec[Throwable,List[Int]] = Valid(List(1, 2, 3))
res0: scala.util.Try[List[Int]] = Failure(java.lang.RuntimeException: boom)

这是第二个问题的解决办法

case class CompoundError(errs: List[Throwable]) extends Throwable

def toTry[T](list: List[Try[T]]): Try[List[T]] =
  list.partition(_.isSuccess) match {
    case (res, Nil) =>
      Success(res.map(_.get))
    case (_, errs) =>
      Failure(CompoundError(errs.collect { case Failure(e) => e }))
  }
分区
操作将成功和失败分开,而
匹配
根据是否存在任何失败返回适当的值


以前的解决方案:

case class CompoundError(errs: List[Throwable]) extends Throwable

def toTry[T](list: List[Try[T]]): Try[List[T]] = {
  val (res, errs) = list.foldLeft((List.empty[T], List.empty[Throwable])) {
    case ((res, errs), item) =>
      item match {
        case Success(t) => (t :: res, errs)
        case Failure(e) => (res, e :: errs)
      }
  }

  errs match {
    case Nil => Success(res.reverse)
    case _ => Failure(CompoundError(errs.reverse))
  }
}

我会质疑因为一次
失败而放弃每一次
成功
的普遍效用。这样一个函数的语义是什么?@YuvalItzchakov我在我的问题中添加了语义-我希望这就是你的意思。@jwvh同样的推理应该适用于
未来
。我只是想知道可能的重复添加
Seq
(在问题中使用)没有
遍历
实例。如果
List
没有问题,那么这就是方法。cats中是否也有一个版本会产生复合错误?@pme您可以将Try转换为Eithers并复合所有的left吗?@pme是的,但您需要将Try更改为Validated,或者更改为其中一个并使用其
并行
实例(后者将使用Validated)。-此外,您的错误类型应该形成一个半群,以便它能够组合错误。@MarioGalic IMHO,最好是
x.toEither.toValidatedNec
。bimap
bimap
有点过于冗长,通常错误应该是非空的,以防出现无效错误,最后列表的串联非常糟糕。因此,
NonEmptyChain
是(对我来说)最好使用的类型。