将flatMap转换为for-understanding

时间:2014-04-25 13:51:58

标签: scala for-comprehension flatmap

给定foobar

scala> def foo: Try[Seq[String]] = Success(List("good", "job"))
foo: scala.util.Try[Seq[String]]

scala> def bar(x: String): Try[String] = Try(x)
bar: (x: String)scala.util.Try[String]

如何将此flatMap转换为for-comprehension

scala> foo.flatMap(a => Try(a.map(c => bar(c))))
res48: scala.util.Try[Seq[scala.util.Try[String]]] = 
         Success(List(Success(good), Success(job)))

请注意,我提供了上述内容作为Using for-comprehension, Try and sequences in Scala的答案,但我无法将其转换为for-comphension

2 个答案:

答案 0 :(得分:1)

你做不到。 for-comprehension只能是一系列flatMap次呼叫,后跟一个map(或所有foreach次呼叫)。对Try的调用打破了链条。你摆脱Try并使用map,但是两个map调用也不能成为单一的理解。

Try.flatMap将捕获传递给flatMap的函数中发生的错误,因此我们可以通过调用get的结果bar来简化返回类型:

foo.map(a => a.map(c => bar(c).get))

我们可以通过缩进其中两个来完成非常接近的理解:

for {
  a <- foo
} yield for {
  c <- a
} yield bar(c).get

产生:

res12: scala.util.Try[Seq[String]] = Success(List(good, job))

答案 1 :(得分:0)

此:

foo.flatMap(a => Try(a.map(c => bar(c))))

相当于:

for {
  a <- foo
} yield a.map(c => bar(c))

至于&#34;展平&#34;内部map进入相同的for - 理解 - 如果你想要结果(即Try的2个等级),那就没有意义了:

Success(List(Success(good), Success(job)))

虽然我的直觉告诉我你可能想要将List[Try[String]]变为List[String]而不管怎样(使用例如.map(_.toOption).flatten),我想wingedsubmariner也在暗示。