TransWikia.com

Обработка нескольких Either

Stack Overflow на русском Asked on November 13, 2021

Имеется 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 без получения вложенностей?

One Answer

Чтобы не было вложенности, можно воспользоваться методом 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 из за его простоты.

Answered by extrn on November 13, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP