2016-12-16 12 views
0

Scala/Sparkの新機能です。私はそれが型の不一致に関係しています知っているが、それはそれについてですScalaのflatMap関数と戻り値の型エラー

val artistID = rawArtistData.flatMap { line => 
    val (id, name) = line.span(_ != '\t') 
    if (name.isEmpty) { 
    None 
    } else { 
    try { 
     (id.toInt, name.trim) 
    } catch { 
     case e: NumberFormatException => None 
    } 
    } 
} 

val artistID = rawArtistData.flatMap { line => 
    val (id, name) = line.span(_ != '\t') 
    if (name.isEmpty) { 
    None 
    } else { 
    try { 
     Some(id.toInt, name.trim) 
    } catch { 
     case e: NumberFormatException => None 
    } 
    } 
} 

そして、これではありません。私はこのコードが受け入れられる理由を把握しようとしています。私の質問はなぜ私はタプルを返すことができないのですか?

答えて

2

で何が起こっているかを確認するには、のは、明確な種類を作ってみよう:

if (name.isEmpty) { 
    None // Option[Nothing] 
    } else { 
    try { 
     Some(id.toInt, name.trim) // Option[(Int, String)] 
    } catch { 
     case e: NumberFormatException => None // Option[Nothing] 
    } 
    } 

何もあなたがNothing succedsと合併しようとするボトム型、および何もありません。したがって、NoneSome(...)の間の統一が常に機能します。List(None, Some(...))で自分で試してみてください。結果は常にList[Option[...]]となります。あなたがそこに

try { 
     Some(id.toInt, name.trim) // (Int, String) 
    } catch { 
     case e: NumberFormatException => None // Option[Nothing] 
    } 

にタプルを持っている場合

は今、コンパイラはそれができない... (Int, String)Option[Nothing]統一しようとします。 Scalaの任意の2つのスーパータイプは常にAnyですが、それはあなたを助けません。 !

(T) ⇒ TraversableOnce[U] 

どちら(_, _)Option[(_, _)]TraversableOnceですが、のコンパニオンオブジェクト:エラーメッセージを取得する理由=オプション

1

これはSparkとあまり関係ないが、Scalaや関数型プログラミングで一般的に使用されている。 flatMap操作は、基になる構造を平坦化します。例えば、List[List[A]]からList[A]、またはOption[Option[A]]からOption[A]です。同様にRDD[List[A]]RDD[A]となり、行はスキップされ、RDD[None]となります。

ここでフラットマップを使用するのは、直感的ではありません。最初にマップを作成してからフィルタ操作を行うこともできます。これは2つの操作を使用するとより高価に見えるかもしれませんが、それらはモナドであるため、Sparkは特に新しいTungsten engineを使用して操作を最適化します。

2

flatMap方法は、次のシグネチャを持つ関数fを必要とタプルので、だから、です

def option2Iterable[A](xo: Option[A]): Iterable[A] 

Iterable[_]TraversableOnce[_]ある:後者は、暗黙option2Iterable方法を有しています。このため、Optionを返すことができ、平文Tuple2[_, _]を返すことはできません。

実際にあなたがTryでこれを簡素化:

import scala.util.Try 

rawArtistData.flatMap { line => Try { 
    line.span(_ != '\t') match { 
    case (id, name) => (id.toInt, name) 
    } 
}.toOption } 
関連する問題