对Try of List元素的RDD的理解

时间:2016-08-22 14:16:57

标签: list scala apache-spark monads for-comprehension

在Spark流程中我有一个RDD[Try[(A, B)]]。我必须使用函数RDD转换此f: B => List[C]。我想要获得的是RDD[Try[(A, B, C)],其中我必须flatMap从函数f的应用程序中获取的列表。

我试过这个:

val tryRdd = // Obtain the RDD[Try[(A, B)]]
val transformedRdd = 
  tryRdd.map {
    pair =>
      for {
        (a, b) <- pair
        c <- f(b)
      } yield {
        (a, b, c)
      }
  }

不幸的是,我得到的是RDD[Try[Nothing]]。为什么?任何人都可以帮我理解我错在哪里吗?

我认为这个问题与RDD并不真正相关。带有RDD的Probabily List将以相同的结果结束。

2 个答案:

答案 0 :(得分:2)

for-comprehension被翻译为

pair.flatMap { case (a, b) => f(b).map { case c => (a, b, c) } }

但是f(b).map(...)会为List[(A, B, C)]的参数提供Try[(A, B, C)],而不是pair.flatMap。所以代码根本不应该编译(除非你在范围内有一个奇怪的隐式转换)。

但是如果你使用的是IntelliJ,它可能无法显示错误并显示错误的类型(或者相反,它可能会显示工作代码中的错误):您需要实际构建项目才能看到真正的错误。

答案 1 :(得分:0)

您是否尝试过正式输入您的RDD?

val transformedRdd : RDD[Try[Tuple3]] = ...

编辑: 如果这确实引起了错误,那么地图的输出是错误的。 pair变量的类型是Try。 由于scala不会为您执行此操作,因此您必须添加一些指令以与其内容(元组(A,B))进行交互。 另外,您不必保留Try类型。 我会使用flatMap来保持成功并清理我的RDD。 像

这样的东西
val transformedRdd = tryRdd.flatMap {value =>
  value match {
    case Success((a,b)) => ...
  }
}

观看http://www.scala-lang.org/api/2.9.3/scala/util/Try.html以获取有关Try类的更多信息。