Ответ 1
Вы выполните либо:
either.left.map(f)
или a:
either.right.map(f)
Вы также можете использовать для понимания: for (x <- either.left) yield f(x)
Здесь более конкретный пример выполнения map
на Either[Boolean, Int]
:
scala> val either: Either[Boolean, Int] = Right(5)
either: Either[Boolean, Int] = Right(5)
scala> val e2 = either.right.map(_ > 0)
either: Either[Boolean, Boolean] = Right(true)
scala> e2.left.map(!_)
either: Either[Boolean, Boolean] = Right(true)
EDIT:
Как это работает? Скажем, у вас есть Either[A, B]
. Вызов left
или right
создает объект LeftProjection
или RightProjection
, который является оболочкой, содержащей объект Either[A, B]
.
Для обертки left
для преобразования Either[A, B]
в Either[C, B]
применяется следующий map
с функцией f: A => C
. Он делает это, используя сопоставление шаблонов под капотом, чтобы проверить, действительно ли Either
left
. Если это так, он создает новый Left[C, B]
. Если нет, то только изменения создают новый Right[C, B]
с тем же базовым значением.
И наоборот для обертки right
. Эффективно, говоря either.right.map(f)
означает - если объект (Either[A, B]
) содержит значение right
, сопоставьте его. В противном случае оставьте его как есть, но измените тип B
для любого объекта, как если бы вы его сопоставили.
Итак, технически эти проекции - просто обертки. Семантически, это способ сказать, что вы делаете то, что предполагает, что значение, хранящееся в объекте Either
, равно либо left
, либо right
. Если это предположение неверно, отображение ничего не делает, но параметры типа изменяются соответствующим образом.