我有以下代码:
val e1 = 10 :: 15 :: 20 :: 25 :: Nil
val e2 = 10 :: 15 :: 20 :: 25 :: Nil
val y = for {
e <- e1 if(e%2==0)
} yield e
val y1 = e1.withFilter(x => (x%2 == 0)).map(Int=>Int)
val e31 = for{
i <- e1
j <- e2 if (isPrime(i+j))
} yield(i,j)
现在您可以看到y
和y1
两个都给了我完全相同的值,这证明我已成功代表for
语句(单一生成器+过滤器)with withFilter和地图。
但是当我有一个带有多个生成器和过滤器的for
语句时(例如:val e31
),我无法找到如何用map,filterMap和withFilter表示它。
答案 0 :(得分:2)
scala> val e31 = for{
| i <- e1
| j <- e2
| if ((i+j) % 2 == 0)
| } yield(i,j)
res1: List[(Int, Int)] = List((10,10), (10,20), (15,15), (15,25), (20,10), (20,20), (25,15), (25,25))
scala> e1.flatMap(i => e2.withFilter(j => ((i+j)%2 == 0)).map(j => (i,j)))
res2: List[(Int, Int)] = List((10,10), (10,20), (15,15), (15,25), (20,10), (20,20), (25,15), (25,25))
请查看this问题,以获得有关每个for-construct如何翻译的更详细答案。
答案 1 :(得分:1)
实际上,有一种方法可以强制Scala编译器向我们展示它如何消除for
理解。
例如,在编译此代码时:
object dummy {
val e31 = for{
i <- e1
j <- e2
if (isPrime(i+j))
} yield(i,j)
}
scalac -Xprint:parser dummy.scala
,你会得到:
[[syntax trees at end of parser]] // dummy.scala
package <empty> {
object dummy extends scala.AnyRef {
def <init>() = {
super.<init>();
()
};
val e31 = e1.flatMap(((i) => e2.withFilter(((j) => isPrime(i.$plus(j)))).map(((j) => scala.Tuple2(i, j)))))
}
}
代码有错误(各种标识符未定义)但这里没关系,因为parser
还没有看到这些错误。