How to convert [Try [_]] option to try [Option [_]]?

I often use the function below to convert Option[Try[_]] to Try[Option[_]] , but it doesn't feel right. Can such functionality be expressed more idiomatically?

 def swap[T](optTry: Option[Try[T]]): Try[Option[T]] = { optTry match { case Some(Success(t)) => Success(Some(t)) case Some(Failure(e)) => Failure(e) case None => Success(None) } } 

Say I have two meanings:

 val v1: Int = ??? val v2: Option[Int] = ??? 

I want to do an op operation (which may fail) on these values ​​and pass this for the function f below.

 def op(x: Int): Try[String] def f(x: String, y: Option[String]): Unit 

I usually use readability for understanding:

 for { opedV1 <- op(v1) opedV2 <- swap(v2.map(op)) } f(opedV1, opedV2) 

PS. I would like to avoid some hard things like climbing.

+6
source share
3 answers

Sounds like Try { option.map(_.get) } will do what you want.

+3
source

The cats library allows you to easily arrange Option to Try :

 scala> import cats.implicits._ import cats.implicits._ scala> import scala.util.{Failure, Success, Try} import scala.util.{Failure, Success, Try} scala> Option(Success(1)).sequence[Try, Int] res0: scala.util.Try[Option[Int]] = Success(Some(1)) scala> Option(Failure[Int](new IllegalArgumentException("nonpositive integer"))).sequence[Try, Int] res1: scala.util.Try[Option[Int]] = Failure(java.lang.IllegalArgumentException: nonpositive integer) scala> None.sequence[Try, Int] res2: scala.util.Try[Option[Int]] = Success(None) 
+3
source

This option avoids reorganization:

 import scala.util.{Failure, Success, Try} def swap[T](optTry: Option[Try[T]]): Try[Option[T]] = optTry.map(_.map(Some.apply)).getOrElse(Success(None)) swap(Some(Success(1))) // res0: scala.util.Try[Option[Int]] = Success(Some(1)) swap(Some(Failure(new IllegalStateException("test")))) // res1: scala.util.Try[Option[Nothing]] = Failure(java.lang.IllegalStateException: test) swap(None) // res2: scala.util.Try[Option[Nothing]] = Success(None) 
+1
source

All Articles