Why is flatMap on Vector [Option [Int]] whose function of the mapping function is not Vector [Option [Int]] valid?

For instance,

Vector(Some(1), Some(2), Some(3), None).flatMap{ n => n } 

creates a Vector(1, 2, 3) instead of giving an error. As I saw in other languages, flatMap used when you have a mapping function that creates nesting, so I expect this to be a valid flatMap :

 Vector(1, 2, 3).flatMap{ eachNum => Vector(eachNum) } 

My mapper function creates a Vector that can cause nesting (i.e. Vector(Vector(1), Vector(2), Vector(3), Vector(4)) ) if I used map because of container packing. However, flatMap will remove this attachment and smooth it. This makes sense when there is a nesting of two identical monads.

However, I don’t understand how using flatMap with the mapper function that returns Option turns a Vector[Option[Int]] into Vector[Int] . Some kind of transformation is taking place (I have never seen this before), can someone explain and maybe point me to some resources?

Thank you very much

+3
source share
2 answers

we can use reify to find out what happens:

 scala> import reflect.runtime.universe._ import reflect.runtime.universe._ scala> val v = Vector(Some(1), Some(2), Some(3), None) v: scala.collection.immutable.Vector[Option[Int]] = Vector(Some(1), Some(2), Some(3), None) scala> reify { v.flatMap(x => x) } res0: reflect.runtime.universe.Expr[scala.collection.immutable.Vector[Int]] = Expr[scala.collection.immutable.Vector[Int]]($read.v.flatMap(((x) => Option.option2Iterable(x)))(Vector.canBuildFrom)) 

This shows us that it uses the option2Iterable transform to convert Option to Iterable , and Iterable is a subtype of the GenTraversableOnce type that GenTraversableOnce expects.

+8
source

The f function passed in flatMap here:

 Vector(Some(1), Some(2), Some(3), None).flatMap{ n => n } 

It is a function of A => GenTraversableOnce[B] , as described in the implementation of flatMap :

 def flatMap[B, That](f : scala.Function1[A, GenTraversableOnce[B]]) (implicit bf : CanBuildFrom[Repr, B, That]) : That = ??? 

The function implemented in your example n => n :

 (n: Option[Int]) => n 

Where A is Option[Int] and B is Int .

Because CanBuildFrom defined as trait CanBuildFrom[-From, -Elem, +To] :

  • From Repr , in which case Vector
  • Elem B , therefore Int

The result is flatMap , therefore, Vector[Int]

+2
source

Source: https://habr.com/ru/post/1241038/


All Articles