Monad捕获多个异常(不单单失败) [英] Monad to catch multiple exceptions (not just fail on single)
问题描述
我有一个类似的问题,在这里提出的问题(多次或单次尝试抓住),然而在我的情况下,我需要遵循这种模式的功能(而不是性能原因)
I have a similar question to what is asked here (Multiple or Single Try Catch), however in my case I need to follow this pattern for functional (and not performance reasons)
本质上我正在处理Scalatra中的参数错误,我需要一个简单的如果有任何转换失败,那么如果没有第一次失败跳过其余的尝试调用,
Essentially I am handling parameter errors in Scalatra, and I need an easy way to catch if any conversions fail without the first failure skipping the rest of the try calls
换句话说,我需要一些跟随这样的样式
In other words, I need something that follows a pattern like this
def checkMultiple(a:Seq[Try]):Either[Map[_,Throwable],Map[_,Success]] = {
???
}
我放入了一个try子句的序列。如果其中任何一个失败,它将返回失败的尝试的全部的映射,而不仅仅是第一个(将有失败的尝试的映射及其异常),否则它将返回所有尝试映射的映射与他们的成功值的映射
I put in a Sequence of try clauses. Should any of them fail, it will return back a map of all of the failed try's , not just the first one (which will have a map of the try that failed, along with its exception), else it will return a map of all of the try's mapped with their success values
有没有人知道是否有一个monadic模式本质上已经这样做,或者如果有一些这样做的util库?否则你将如何定义上述函数?
Does anyone know if there is a monadic pattern that already does this in essence, or if there is some util library which does this? Else how would you define the above function?
推荐答案
你可以用简单的Scala来完成一些这样的事情,虽然它有点多工作比Scalaz'验证
。
You can accomplish something much like this with plain Scala, though it's a little more work than with 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))
这篇关于Monad捕获多个异常(不单单失败)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!