Преобразование опции в Либо в Scala

Предположим, мне нужно преобразовать Option[Int] в Either[String, Int] в Scala. Я хотел бы сделать это следующим образом:

def foo(ox: Option[Int]): Either[String, Int] =
  ox.fold(Left("No number")) {x => Right(x)}

К сожалению, приведенный выше код не компилируется, и я должен явно указать тип Either[String, Int]:

  ox.fold(Left("No number"): Either[String, Int]) {x => Right(x)}

Можно ли преобразовать Option в Either таким образом, не добавляя тип?
Как бы вы предложили преобразовать Option в Either?

Ответы

Ответ 1

Нет, если вы так делаете, вы не можете оставить этот тип.

Тип Left("No number") определяется как Either[String, Nothing]. Из всего Left("No number") компилятор не может знать, что вы хотите, чтобы второй тип Either был Int, а вывод типа не зашел так далеко, что компилятор будет смотреть на весь метод и решить, что он должен be Either[String, Int].

Вы можете сделать это несколькими способами. Например, при сопоставлении с образцом:

def foo(ox: Option[Int]): Either[String, Int] = ox match {
  case Some(x) => Right(x)
  case None    => Left("No number")
}

Или с выражением if:

def foo(ox: Option[Int]): Either[String, Int] =
  if (ox.isDefined) Right(ox.get) else Left("No number")

Или с помощью Either.cond:

def foo(ox: Option[Int]): Either[String, Int] =
  Either.cond(ox.isDefined, ox.get, "No number")