如何转换选项[试试[_]]试试[选项[_]]?

kop*_*zko 7 scala optional traversable

我经常使用下面的函数转换Option[Try[_]]Try[Option[_]]但感觉不对.可以用更惯用的方式表达这样的功能吗?

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)
  }
}
Run Code Online (Sandbox Code Playgroud)

说我有两个值:

val v1: Int = ???
val v2: Option[Int] = ???
Run Code Online (Sandbox Code Playgroud)

我想op对这些值进行操作(可能会失败)并将其传递给f下面的函数.

def op(x: Int): Try[String]
def f(x: String, y: Option[String]): Unit
Run Code Online (Sandbox Code Playgroud)

我通常用于理解可读性:

for {
  opedV1 <- op(v1)
  opedV2 <- swap(v2.map(op))
} f(opedV1, opedV2)
Run Code Online (Sandbox Code Playgroud)

PS.我想避免像scalaz这样沉重的东西.

jub*_*0bs 6

库允许你排序Option一个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)
Run Code Online (Sandbox Code Playgroud)


Dim*_*ima 4

听起来像是Try { option.map(_.get) }会做你想做的事。

  • 在我看来,像这样抛出和捕获异常有足够的开销(例如在运行时,但对读者来说更重要),OP 实现是更可取的,即使它不太简洁。 (9认同)
  • 抛出异常的开销是多少(除了实例化它并填充堆栈,这现在已经完成了)?我不知道它比调用函数大得多。无论如何,我认为,如果一个人关心抛出异常的开销,那么他一开始就不应该使用“Try”。或者 scala 也同样如此(scala 中的某些东西会带来更多的开销,并且比异常更难避免)。只需坚持使用“C”和 goto 即可确保最大限度地减少开销:) (2认同)
  • 嗯,那太糟糕了。我总是为聪明人破例。我发现他们很难得到,值得时不时地受到与愚蠢的人不同的对待;) (2认同)