Обработка нескольких Either
Имеется 3 метода возвращающие Either, которые необходимо вызывать последовательно и если предыдущий вернул Right. Вернуть надо только результат последнего Either. Как правильно их обработать, чтобы не потерять Left, в случае возникновения ошибки и чтобы не было вложенности вида Either[Either[Either...]]].
def doSmth1: Either[Exception, String] = {}
def doSmth2: Either[Exception, String] = {}
def doSmth3: Either[Exception, String] = {}
Пробовал обрабатывать так:
doSmth1.map(s1 => {/** do something */
doSmth2.map({
doSmth3.map({
//do something
})
})
})
Но вложенность получается Either[Either[Either...]]]. Можно обрабатывать через for comprehensions:
for (
s1 <- doSmth1
s2 <- doSmth2
s3 <- doSmth3
) yield
Как вычислить Either без получения вложенностей?
Ответы (1 шт):
Чтобы не было вложенности, можно воспользоваться методом Either.flatten.
doSmth1.map(s1 =>
doSmth2.map(s2 =>
doSmth3.map(s3 => /* do something with s1, s2, */ s3)
).flatten
).flatten
А еще лучше методом, который объединяет map и flatten
doSmth1.flatMap(s1 =>
doSmth2.flatMap(s2 =>
doSmth3.map(s3 => /* do something with s1, s2, */ s3)
)
)
Примерно такой код и сгенерирует компилятор при использовании следующей конструкции
for {
s1 <- doSmth1
s2 <- doSmth2
s3 <- doSmth3
} yield /* do something with s1, s2, */ s3
Для вашего же случая, когда s1 и s2 не важны, а s3 используется без изменения, получаем следующее выражение, применив тождественные преобразования
doSmth1 flatMap (_ => doSmth2) flatMap (_ => doSmth3)
Можете выбрать любой вариант, но я бы остановился на for comprehension из за его простоты.