2017-10-08 5 views
4

flatMapの使用方法をScalaコンパイラがどのように計算して、Optionのシーケンスであるのかわかりません。"flatMap"はScalaのOptionタイプのシーケンスで動作するのはなぜですか?

私は、配列の配列にflatMapを使用する場合:

println(Seq(Some(1), None).flatMap(a => a)) // List(1) 
:それは私が Option秒の順序でそれを使用する場合

同じ問題が発生したすべてのネストされたシーケンスを連結します

println(Seq(Seq(1), Seq()).flatMap(a => a)) // List(1) 

したがって、flatMapはこの場合はOptionをコレクションとして扱います。問題はなぜこれが機能するのか?それはGenTraversableOnceのインスタンスを返しますが、OptionGenTraversableOnceを継承していない機能を期待していることの意味

def flatMap[B, That](f: A => GenTraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That 

flatMapは、次のように定義されています。それはProductSerializableを継承し、ProductEqualsを継承します。

この場合、ScalaコンパイラはOptionのシーケンスでflatMapをどのように使用できますか?

+2

を、これも事実 'オプション[A]'から生じるが、* *モナドでありますオプションフラットマップの汎用シグネチャのためにぼやけてしまいます。 'option [A]'の 'flatMap'(そうでなければ' bind'という名前)は本当に 'def flatMap(f:A => Option [B]):オプション[B]'でなければなりません。スカラズやネコなどの図書館。 –

答えて

4

あなたの観察は正しいです。コンパイラが型を一致させることができない場合は、この場合には、それは暗黙の型変換を探し、Optionのコンパニオンオブジェクトで見つかる:

import scala.language.implicitConversions 

/** 
    An implicit conversion that converts an option to an iterable value 
*/ 

implicit def option2Iterable[A](xo: Option[A]): Iterable[A] = xo.toList 

これはIterable sとOption秒を治療することが可能となります。


また、あなたのコードはflatten使用して簡素化することができます。これはあるもののGrzegorzsの答えに追加するには

Seq(Some(1), None).flatten 
関連する問題