Let's assume that I have two lists of calculation results
val a: List[ Throwable \/ A] = ...
val b: List[ Throwable \/ B] = ...
and I have function which is calculating final result such as
def calc(a: A, b: B): Throwable \/ C = ...
I need to calculate all results for every a
and b
and also to accumulate Throwable
if there are some.
Is there any elegant way like Applicative style <*>
?
UPDT: The result must be the following
val c: List[ Throwable \/ C] ..
The best solutuion that I came to is
def combine[A, B, C](f: (A, B) => Throwable \/ C, a: Throwable \/ A, b: Throwable \/ B): List[Throwable] \/ C = (a, b) match{
case ( -\/(errA), \/-(_)) => -\/(List(errA))
case (\/-(_), -\/(errB)) => -\/(List(errB))
case (-\/(errA), -\/(errB)) => -\/(List(errA, errB))
case (\/-(valA), \/-(valB)) => f(valA, valB).leftMap( List(_))
}
And than
val result = (a |@| b)(combine(calc, _, _))
But in that case I have some extra results. And result list has type List[ List[Throwable] \/ C]