Предположим, что у меня есть два списка результатов вычислений
val a: List[ Throwable \/ A] = ...
val b: List[ Throwable \/ B] = ...
и у меня есть функция, которая вычисляет конечный результат, например
def calc(a: A, b: B): Throwable \/ C = ...
Мне нужно рассчитать все результаты для каждого a
и b
, а также накопить Throwable
, если они есть. Есть ли какой-нибудь элегантный способ, подобный аппликативному стилю <*>
?
UPDT: результат должен быть следующим
val c: List[ Throwable \/ C] ..
Лучшее решение, к которому я пришел, это
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(_))
}
И тогда
val result = (a |@| b)(combine(calc, _, _))
Но в этом случае у меня есть некоторые дополнительные результаты. И список результатов имеет тип List[ List[Throwable] \/ C]