2016-01-10 13 views
16

Supponiamo ho bisogno di convertire Option[Int]-Either[String, Int] a Scala. Mi piacerebbe farlo in questo modo:Converti Opzione per entrambi i casi a Scala

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

Purtroppo il codice di cui sopra non compila e ho bisogno di aggiungere tipo Either[String, Int] esplicitamente:

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

E 'possibile convertire Option a Either questo modo senza aggiungere il tipo?
Come ti suggeriscono di convertire Option a Either?

risposta

28

No, se lo si fa in questo modo, non si può lasciare fuori il tipo.

Il tipo di Left("No number") viene dedotta per essere Either[String, Nothing]. A partire dal Left("No number") il compilatore non può sapere di volere che il secondo tipo di sia Int e che l'inferenza di tipo non si spinga così lontano che il compilatore osserverà l'intero metodo e deciderà che dovrebbe essere Either[String, Int].

Si potrebbe fare questo in un certo numero di modi diversi. Ad esempio, con il pattern matching:

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

o con un if espressione:

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

O con Either.cond:.

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

'ox.map (destro (_)) getOrElse (Sinistra ("Nessun numero")) "funziona pure, ma crea un'istanza intermedia" Opzione ". – knutwalker

+7

E c'è anche 'ox.toRight (" Nessun numero ")' ma poiché questo metodo non ha un tipo di ritorno esplicito, viene inferito a 'Serializable con prodotto con o [String, Int] ' – knutwalker

+0

@knutwalker Oh, grazie . Mi piace la tua soluzione 'toRight'. Aggiungerò semplicemente il tipo: 'ox.toRight (" Nessun numero "): O [String, Int]'. – Michael

Problemi correlati