Monad to catch a few exceptions (not just crashing on one)

I have a similar question about what is being asked here ( Multiple or single Try Catch ), however in my case I need to follow this pattern for functional (and not performance)

Essentially, I handle 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]] = { ??? } 

I put in a sequence of try sequences. If any of them fails, he will return a map of the entire failed attempt, and not just the first (which will have a map of the failed attempt, as well as its exception), otherwise he will return a map of all attempts mapped to their success values

Does anyone know if there is a monadic pattern that already does this essentially, or if there is some kind of utility library that does this? Otherwise, how would you define the above function?

+1
source share
1 answer

You can do something similar with the usual Scala, although this is slightly larger than the 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) } 

Here it works:

 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)) 
+3
source

Source: https://habr.com/ru/post/1500065/


All Articles