Во-первых: по соглашению (импортировано из Haskell, где это имело смысл) ошибки равны Left
, а правильные значения Right
.
Как только мы установим sh это соглашение: .map
позволяет отображать правильное значение (оно оставляет значение Left
нетронутым), в то время как .flatMap
позволяет превратить значение Right
в Left
или Right
- при Right
оно продолжит композицию, а Left
будет разорвать цепь.
Имея:
val a: Either[Exception, Value]
val b: Either[Exception, Value]
val c: Either[Exception, Value]
вы можете написать:
val abc: Either[Exception, Value] =
a.flatMap { aValue =>
b.flatMap { bValue =>
c.map { cValue =>
(aValue, bValue, cValue)
}
}
}
, что благодаря пониманию может быть записано короче как:
val abc = for {
aValue <- a
bValue <- b
cValue <- c
} yield (aValue, bValue, cValue)
Однако, если вы используете java.lang.Exception
в качестве ошибки, то имеет смысл использовать Try
, потому что Try[A]
очень похож на Either[Throwable, A]
, за исключением того, что он также может перехватывать исключения, возникающие внутри него. (и короче, чтобы написать).