-1

我有以下代码:

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)

现在正如您所看到的yy1两者都给了我完全相同的值,这证明我成功地表示for了具有(单个生成器 + 过滤器)与 withFilter 和 map 的语句。

但是当我有一个for包含多个生成器和过滤器的语句(例如:val e31)时,我无法找出如何用 map、filterMap 和 withFilter 来表示它。

4

2 回答 2

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))

看一下这个问题,以获得关于如何翻译每个 for-construct 的更详细的答案。

于 2013-11-09T16:13:35.540 回答
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还没有看到这些错误。

于 2013-11-09T16:21:10.380 回答