2

给定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.

4

2 回答 2

1

你不能。一个 for-comprehension 只能是一个flatMap调用序列,后跟一个map(或所有foreach调用)。调用Try中断链。您摆脱了Tryand use map,但是两个map调用也不能成为一个单一的理解。

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

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))
于 2014-04-26T02:20:50.100 回答
0

这个:

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

相当于:

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

至于将内部“扁平化”map为相同的for理解 - 如果您希望结果是(即 2 个级别),那就没有意义了Try

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

尽管我的直觉告诉我,您可能还是希望将 to 变平List[Try[String]]List[String]使用 eg .map(_.toOption).flatten),但我猜 wingedsubmariner 也建议这样做。

于 2014-04-26T02:40:57.370 回答