Monad可以捕获多个异常(而不仅仅是单个异常失败)



我有一个类似于这里所问的问题(多次或单次尝试捕获),但在我的情况下,出于功能(而非性能原因),我需要遵循此模式

从本质上讲,我正在处理Scalatra中的参数错误,如果任何转换失败,我需要一种简单的方法来捕捉,而不会出现第一次失败跳过其余的try调用

换句话说,我需要一个类似模式的东西

  def checkMultiple(a:Seq[Try]):Either[Map[_,Throwable],Map[_,Success]] = {
    ???
  }

我加入了一系列try子句。如果其中任何一个失败,它将返回失败尝试的所有的映射,而不仅仅是第一个(它将有一个失败尝试的映射及其异常),否则它将返回一个映射了成功值的所有尝试的映射

有人知道是否有一个monadic模式已经在本质上做到了这一点,或者是否有一些util库做到了?否则,您将如何定义上述函数?

使用普通Scala可以完成类似的任务,尽管它比使用Scalaz的Validation要多一些。

def checkMultiple[A,B](data: Seq[A])(f: A => B): Either[Map[A,Throwable], Map[A,B]] = {
  val caught = data.map(a => a -> Try(f(a)))
  val wrong = caught.collect{ case (a, Failure(t)) => a -> t }
  if (!wrong.isEmpty) Left(wrong.toMap)
  else Right(caught.map(x => x._1 -> x._2.get).toMap)
}

它在工作:

scala> checkMultiple(Seq(1,2,3,4))(x => if (x>4) throw new Exception else x)
res1: scala.util.Either[Map[Int,Throwable],Map[Int,Int]] = 
  Right(Map(1 -> 1, 2 -> 2, 3 -> 3, 4 -> 4))
scala> checkMultiple(Seq(3,4,5,6))(x => if (x>4) throw new Exception else x)
res2: scala.util.Either[Map[Int,Throwable],Map[Int,Int]] = 
  Left(Map(5 -> java.lang.Exception, 6 -> java.lang.Exception))

相关内容

最新更新