用于实现flatMap的scala中的理解

时间:2015-08-11 22:27:03

标签: scala for-loop

教授。 Coursera课程中的Odersky使用for循环实现type mismatch; found : play.api.mvc.Action[play.api.mvc.AnyContent] required: scala.concurrent.Future[play.api.mvc.Result] 如下:

flatMap

这里有两个函数的一些应用程序(按预期结果):

def flatMap[T, U](xs: List[T], f: T => Iterable[U]) = for (x <- xs; y <- f(x)) yield y

然而,当我尝试将flatMap实现为:

val xs = List(1, 2, 3, 4, 5)
flatMap[Int, Int](xs, x=> List(x /2))

它没有返回正确的答案,它返回一个列表列表(它应该返回一个包含内部列表的所有元素的大列表)

我的问题是,使for (x <- xs) yield f(x) 按预期工作的不同之处是什么;两者之间:

flatMap

为什么for (x <- xs; y <- f(x)) yield y //And for (x <- xs) yield f(x) 没有编译?

1 个答案:

答案 0 :(得分:0)

您的第二个版本根本不涉及对flatMap的调用。你可以使用reify来解除理解,然后看看:

scala> import reflect.runtime.universe._
import reflect.runtime.universe._

scala> val f: Int => Iterable[Int] = null
f: Int => Iterable[Int] = null

scala> val xs = List(1, 2, 3, 4, 5)
xs: List[Int] = List(1, 2, 3, 4, 5)

scala> reify { for (x <- xs; y <- f(x)) yield y }
res0: reflect.runtime.universe.Expr[List[Int]] = Expr[List[Int]]($read.xs.flatMap(((x) => $read.f.apply(x).map(((y) => y))(Iterable.canBuildFrom)))(List.canBuildFrom))

scala> reify { for (x <- xs) yield f(x) }
res1: reflect.runtime.universe.Expr[List[Iterable[Int]]] = Expr[List[scala.Iterable[Int]]]($read.xs.map(((x) => $read.f.apply(x)))(List.canBuildFrom))

第一个可以简化为:

xs.flatMap(x => f(x).map(identity))

相当于:

xs.flatMap(f)

,第二个可以简化为:

xs.map(f)