为什么映射器函数结果不是 Vector[Option[Int]] 的 Vector[Option[Int]] 上的 flatMap 有效?
Why is flatMap on a Vector[Option[Int]] whose mapper function result is not a Vector[Option[Int]] valid?
例如,
Vector(Some(1), Some(2), Some(3), None).flatMap{
n => n
}
生成 Vector(1, 2, 3)
而不是给出错误。正如我在其他语言中看到的那样,当您具有生成嵌套的映射器函数时使用 flatMap
所以我希望这是一个有效的 flatMap
:
Vector(1, 2, 3).flatMap{
eachNum => Vector(eachNum)
}
我的映射器函数生成一个 Vector
,如果我使用 map
,这将导致嵌套(即 Vector(Vector(1), Vector(2), Vector(3), Vector(4))
),因为容器包装。但是,flatMap
将删除此嵌套并将其展平。当两个相同的单子嵌套时,这是有道理的。
但是,我不明白如何将 flatMap
与 returns 和 Option
的映射函数一起使用会使 Vector[Option[Int]]
变成 Vector[Int]
。是否正在发生某种转变(我以前从未见过),有人可以解释一下并给我一些资源吗?
非常感谢
函数 f
在 flatMap
中传递:
Vector(Some(1), Some(2), Some(3), None).flatMap{
n => n
}
是一个函数 A => GenTraversableOnce[B]
,如 flatMap
实现中所述:
def flatMap[B, That](f : scala.Function1[A, GenTraversableOnce[B]])
(implicit bf : CanBuildFrom[Repr, B, That])
: That = ???
您的示例n => n
中实现的功能是:
(n: Option[Int]) => n
其中 A
是 Option[Int]
,B
是 Int
。
因为CanBuildFrom
定义为trait CanBuildFrom[-From, -Elem, +To]
:
From
是 Repr
,在这种情况下 Vector
Elem
是 B
所以 Int
因此flatMap
的结果是Vector[Int]
我们可以使用reify
看看发生了什么:
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))
这向我们展示了它正在使用 option2Iterable 转换将 Option
转换为 Iterable
,并且 Iterable
是 GenTraversableOnce
类型的子类型,flatMap期待中
例如,
Vector(Some(1), Some(2), Some(3), None).flatMap{
n => n
}
生成 Vector(1, 2, 3)
而不是给出错误。正如我在其他语言中看到的那样,当您具有生成嵌套的映射器函数时使用 flatMap
所以我希望这是一个有效的 flatMap
:
Vector(1, 2, 3).flatMap{
eachNum => Vector(eachNum)
}
我的映射器函数生成一个 Vector
,如果我使用 map
,这将导致嵌套(即 Vector(Vector(1), Vector(2), Vector(3), Vector(4))
),因为容器包装。但是,flatMap
将删除此嵌套并将其展平。当两个相同的单子嵌套时,这是有道理的。
但是,我不明白如何将 flatMap
与 returns 和 Option
的映射函数一起使用会使 Vector[Option[Int]]
变成 Vector[Int]
。是否正在发生某种转变(我以前从未见过),有人可以解释一下并给我一些资源吗?
非常感谢
函数 f
在 flatMap
中传递:
Vector(Some(1), Some(2), Some(3), None).flatMap{
n => n
}
是一个函数 A => GenTraversableOnce[B]
,如 flatMap
实现中所述:
def flatMap[B, That](f : scala.Function1[A, GenTraversableOnce[B]])
(implicit bf : CanBuildFrom[Repr, B, That])
: That = ???
您的示例n => n
中实现的功能是:
(n: Option[Int]) => n
其中 A
是 Option[Int]
,B
是 Int
。
因为CanBuildFrom
定义为trait CanBuildFrom[-From, -Elem, +To]
:
From
是Repr
,在这种情况下Vector
Elem
是B
所以Int
因此flatMap
的结果是Vector[Int]
我们可以使用reify
看看发生了什么:
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))
这向我们展示了它正在使用 option2Iterable 转换将 Option
转换为 Iterable
,并且 Iterable
是 GenTraversableOnce
类型的子类型,flatMap期待中