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

半城伤御伤魂 提交于 2019-12-09 17:24:04

问题


I quite often use the function below to convert Option[Try[_]] to Try[Option[_]] but it feels wrong. Can be such a functionality expressed in more idiomatic way?

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 values:

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

I want to make an operation op (which can fail) on these values and pass that to function f below.

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

I typically use for comprehension for readability:

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

PS. I'd like to avoid some heavy stuff like scalaz.


回答1:


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




回答2:


The cats library allows you to sequence an Option to a Try very easily:

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:


This variant avoids rethrowing:

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)


来源:https://stackoverflow.com/questions/36699826/how-to-convert-optiontry-to-tryoption

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!