Scala按嵌套筛选选项/尝试单子

Scala按嵌套筛选选项/尝试单子,scala,monads,Scala,Monads,在Scala中,我有一个数组[Option[(String,String,Try[String])]并希望找到所有故障错误代码 如果内部单子是一个选项[String],我可以用一个干净的小图标访问一些(x)内容以便于理解,如下所示: for { Some(row) <- row (a,b,c) = row x <- c } yield x 用于{ Some(row)返回一个数组[Throwable] for { (_,_,Failure(e)) <- ro

在Scala中,我有一个
数组[Option[(String,String,Try[String])]
并希望找到所有故障错误代码

如果内部单子是一个
选项[String]
,我可以用一个干净的小图标访问
一些(x)
内容以便于理解,如下所示:

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

Some(row)返回一个
数组[Throwable]

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

为了组合不同类型的“单子”,您需要所谓的单子转换器。简单地说,Scala不允许您在同一个单子中混合不同的单子类型以进行理解-这是有意义的,因为理解的单子只是map/flatMap/filter组合的语法糖

假设第一个选项始终是
选项
,则可以将
Try
转换为
选项
,并获得所需的结果:

用于{
一些((a,b,c))将
a.map(u.u 3).过滤器(u.isFailure)
do

编辑:在看过编辑和你的评论之后,我想你也可以这样做

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

tries.filter(_.isFailure)
val trys=for{

x谢谢。这正是我因为过度考虑理解和匹配协议而错过的简单答案。我不得不在开始时添加一个平面图来删除该选项(请参见编辑)。哦,等等…没有看到您的编辑…您必须执行类似
a.flatMap(x=>x.map(u._3)).filter(u.isFailure)的操作
?完全正确。我只需要删除选项部分。我认为可能有更好的方法来处理这两个monad,但它都可以工作,我不想重新编写整个解决方案以使其更干净。我没有考虑到这一点。monad组合限制的优点是。我确实需要失败的内容,所以这不起作用对我来说,但知道这一点很有帮助。谢谢。我建议使用模式匹配。在这种情况下,这是最干净的解决方案:)
val tries = for {
    x <- a
    z <- x
} yield z._3

tries.filter(_.isFailure)