2012-07-11 7 views
15

私は混乱しています。 TraversableLikeでは、機能flatMapは署名オプションはGenTraversableOnceですか?

flatMap[B](f: (A) ⇒ GenTraversableOnce[B]): Iterable[B]

であり、それが可能である理由しかし、私はこのように

scala> Iterable(1,2,3,4,5).flatMap{i=>if (i%2==0) {None} else {Some(i)}} 
res1: Iterable[Int] = List(1, 3, 5) 

をそれを使用することができますか? OptionはどのようにしてGenTraversableOnceに変換されますか?それはサブクラスのようには見えません...

答えて

15

実際には、デフォルトでSome [X]からGenTraversableOnce [X]への暗黙の変換があります。これは、REPLでテストするのが非常に簡単です。

scala> implicitly[Function[Some[Int],GenTraversableOnce[Int]]] 
res1: Some[Int] => scala.collection.GenTraversableOnce[Int] = <function1> 

scala> implicitly[Some[Int] => GenTraversableOnce[Int]] // alternative syntax 
res2: Some[Int] => scala.collection.GenTraversableOnce[Int] = <function1> 

実際、これはオブジェクトオプションで定義されています。スカラパッケージ内:

object Option { 
    /** An implicit conversion that converts an option to an iterable value 
    */ 
    implicit def option2Iterable[A](xo: Option[A]): Iterable[A] = xo.toList 

    /** An Option factory which creates Some(x) if the argument is not null, 
    * and None if it is null. 
    * 
    * @param x the value 
    * @return Some(value) if value != null, None if value == null 
    */ 
    def apply[A](x: A): Option[A] = if (x == null) None else Some(x) 

    /** An Option factory which returns `None` in a manner consistent with 
    * the collections hierarchy. 
    */ 
    def empty[A] : Option[A] = None 
} 

option2Iterableはあなたが探しているものです。また、REPLでのテスト時に、GenTraversableOnceの実装がリストであることがわかります。

あなたは自動的にあなたが見ている(あなたが暗黙的に使用してREPLで見ることができるような)何もしないで輸入されている暗黙の型変換を探している場合:

  • Predef.scala
  • クラス
+1

"REPLで暗黙にテストするのは非常に簡単です[関数[Some [Int]、GenTraversableOnce [Int]]]' -__-単純明示的、はい、大括弧で囲まれています「シンプルな」イホを呼んでいる。 –

+2

グレート答え、感謝ダン –

+0

:スカラ>輸入scala.collection.GenTraversableOnce 輸入scala.collection.GenTraversableOnce スカラ>型OptionToTraversableConversion [X] =関数[オプション[X]、GenTraversableOnce [X]] 定義型の別名OptionToTraversableConversion スカラ>暗黙的に[OptionToTraversableConversion [INT]] RES3:オプション[INT] => scala.collection.GenTraversableOnce [INT] = Edmondo1984

3

実際には暗黙のうちにListに変換されているようです。

scala> val l:scala.collection.GenTraversableOnce[Int] = Some(3) 
l: scala.collection.GenTraversableOnce[Int] = List(3) 

scala> val l:scala.collection.GenTraversableOnce[Int] = None 
l: scala.collection.GenTraversableOnce[Int] = List() 

個人的なメモ:スカラー魔法の暗黙的な変換は時には本当に混乱します。

18

のコンパニオンオブジェクトは、クラス図(*)で見ることができるように、OptionGenTraversableOnceのサブクラスではありませんが、012でIterableで利用可能な暗黙の変換が、あります。

enter image description here

(*)うん、[OK]を、私はだまさ。クラス図はScaladocではまだ利用できませんが、明日になるはずです! :-)

+0

が視覚的には何が起こっているのかかなりよく示して!これはEdmondoの答えと組み合わせて受け入れられるべきです(そしてKarel'sはもっと簡単ですが、より多くの証拠も提供します) – Aktau

+0

は2.10でしかありませんか? – Edmondo1984

+0

@ Edmondo1984確かに、あなたの2.9.2のニーズに合わせて2.10のスカードックを見ることからあなたを止めるものは何もありません。ほとんどの時間は同じです。 –

関連する問題