2016-01-10 5 views
16

ScalaでOption[Int]Either[String, Int]に変換する必要があるとします。私はこのようにそれをやってみたい:オプションをスカラでどちらかに変換する

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)} 

はそれがEitherこれにOptionを変換することが可能ですタイプを追加せずに?
どうすればOptionEitherに変換するといいですか?

答えて

28

いいえ、このようにすると、そのタイプを省略できません。

Left("No number")のタイプは、Either[String, Nothing]と推定されます。ちょうどLeft("No number")から、コンパイラは、の第2の型を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(右(_))getOrElse(左( "No number")) 'も同様に機能しますが、中間の' Option'インスタンスを作成します。 – knutwalker

+7

また、 'ox.toRight(" No Number ")'もありますが、このメソッドは明示的な戻り値の型を持たないため、 'Serializable with Product [String、Int] 'のように推測されます。 – knutwalker

+0

@ knutwalker 。私はあなたの 'toRight'ソリューションが好きです。私はちょうどタイプを追加します: 'ox.toRight(" No Number "):[String、Int]'のいずれかです。 – Michael

関連する問題