3

例如,

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

产生 aVector(1, 2, 3)而不是给出错误。正如我在其他语言中看到的那样,flatMap当你有一个产生嵌套的映射器函数时使用它,所以我希望这是一个有效的flatMap

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

如果我使用 a由于容器包装,我的映射器函数会产生一个Vector会导致嵌套(即)。但是,将删除此嵌套并将其展平。当嵌套两个相同的单子时,这是有道理的。Vector(Vector(1), Vector(2), Vector(3), Vector(4))mapflatMap

但是,我不明白如何将 aflatMap与返回 an 的映射器函数一起使用Option使 aVector[Option[Int]]变为Vector[Int]. 是否正在进行某种转变(我以前从未见过这种情况),有人可以解释一下并可能指出一些资源吗?

非常感谢

4

2 回答 2

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 转换来转换Optionto Iterable,并且IterableGenTraversableOnceflatMap 期望的类型的子类型。

于 2016-01-12T05:08:26.837 回答
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]BInt

因为CanBuildFrom被定义为trait CanBuildFrom[-From, -Elem, +To]

  • FromRepr,在这种情况下Vector
  • ElemB这样的Int

因此的结果flatMapVector[Int]

于 2016-01-12T04:12:19.853 回答