2016-01-10 2 views
16

Предположим, мне нужно преобразовать Option[Int] в Either[String, Int] в Scala. Я хотел бы сделать это следующим образом:Преобразование опции в Либо в 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?

ответ

28

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

Предполагается, что тип Left("No number") будет Either[String, Nothing]. От всего Left("No number") компилятор не может знать, что вы хотите, чтобы второй тип Either был Int, и введите вывод не так далеко, что компилятор будет смотреть на весь метод и решить, что он должен быть 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") 
+0

'ox.map (Right (_)) getOrElse (слева («Нет числа»)) 'работает, но создает промежуточный экземпляр« Option ». – knutwalker

+7

И есть также 'ox.toRight (« No Number »)', но поскольку этот метод не имеет явного типа возврата, он выводится на 'Serializable with Product with Lither [String, Int]' – knutwalker

+0

@knutwalker О, спасибо , Мне нравится ваше решение 'toRight'. Я просто добавлю тип: 'ox.toRight (« No Number »): либо [String, Int]'. – Michael