例如,
Vector(Some(1), Some(2), Some(3), None).flatMap{
n => n
}
生成Vector(1, 2, 3)
而不是出错。正如我在其他语言中看到的那样,当你有一个生成嵌套的mapper函数时会使用flatMap
,所以我希望这是一个有效的flatMap
:
Vector(1, 2, 3).flatMap{
eachNum => Vector(eachNum)
}
我的mapper函数产生一个Vector
,如果由于容器包装而使用Vector(Vector(1), Vector(2), Vector(3), Vector(4))
,则会导致嵌套(即map
)。但是,flatMap
将删除此嵌套并将其展平。当有两个相同的monad嵌套时,这是有意义的。
但是,我不明白如何使用带有flatMap
的映射器函数的Option
使Vector[Option[Int]]
成为Vector[Int]
。是否存在某种转变(我以前从未见过这种转变),有人可以解释并且可能指向我一些资源吗?
非常感谢
答案 0 :(得分:8)
我们可以使用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
是flatMap期待的GenTraversableOnce
类型的子类型
答案 1 :(得分:3)
此处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]