Scala 按嵌套 Option/Try monads 过滤

Scala filter by nested Option/Try monads

在 Scala 中,我有一个 Array[Option[(String,String,Try[String])]] 并且想找到所有失败错误代码。

如果内部 monad 是一个 Option[String],我可以访问 Some(x) 的内容,并且有一点清晰的理解,就像这样:

for {
  Some(row) <- row 
  (a,b,c) = row 
  x <- c
} yield x

但是如果内部 monad 是失败的,那么我很难看到如何对其进行模式匹配,因为我不能将 Failure(x) <- c 放在 for 语句中。这感觉就像我错过的一件非常简单的事情,但任何指导都会非常有价值。

非常感谢!

编辑 - 数组指定错误。它实际上是一个 option-tuple3 的数组,而不仅仅是 tuple3。

这个returns一个Array[Throwable]

for {
  (_,_,Failure(e)) <- rows
} yield e

或者,也许是无糖版本。

rows.collect{case (_,_,Failure(e)) => e}

为了组合不同类型的 "monads",您将需要所谓的 monad 转换器。简而言之,Scala 不允许您在同一个 for comprehension 中混合不同的 monad 类型——这是有道理的,因为 for comprehension 只是 map / flatMap / filter 组合的语法糖。

假设第一个始终是 Option 那么您可以将 Try 转换为 Option 并获得所需的结果:

for {
  Some((a, b, c)) <- row
  x               <- c.toOption
} yield x

如果您真的不关心 Try 里面的内容,那很好,但是如果您这样做了,那么请注意您在 Some(x) 时会丢失这些信息。如果模式匹配失败,那么你将得到一个 None.

希望对你有所帮助。

a.map(_._3).filter(_.isFailure)会吗?

编辑:在看到编辑和您的评论后,我认为您也可以这样做

val tries = for {
    x <- a
    z <- x
} yield z._3

tries.filter(_.isFailure)