具有多个生成器的for循环如何在Scala中工作?

mil*_*box 3 for-loop scala nested-loops

我是Scala的新手,从命令性的背景来看这个,但我想用功能术语来理解它.我对以下代码片段的行为非常困惑.

val res = for {
  i <- 1 to 2
  j <- 1 to 2
} yield (i, j)

println(s"res is $res")
Run Code Online (Sandbox Code Playgroud)

此代码将打印res是Vector((1,1),(1,2),(2,1),(2,2))如预期的那样.但是稍微修改上面的内容

val res = for {
  i <- 1 to 2
  j <- i to 0
} yield (i, j)

println(s"res is $res")
Run Code Online (Sandbox Code Playgroud)

打印res是Vector()

为什么第二个版本的循环不会产生Vector((1,1),(1,0),(2,2),(2,1),(2,0))?

这种行为对我使用Scala中的索引遍历2D矩阵的能力产生了重大影响.一般来说,如何在一个惯用的方式中循环遍历矩阵的上三角部分,同时跟踪行和列索引?

jwv*_*wvh 5

让REPL告诉你.

scala> 1 to 2
res0: scala.collection.immutable.Range.Inclusive = Range 1 to 2

scala> 1 to 0
res1: scala.collection.immutable.Range.Inclusive = empty Range 1 to 0
                                                   ^^^^^
Run Code Online (Sandbox Code Playgroud)

Range除非你告诉它,否则A 不会向下移动.

val res = for {
  i <- 1 to 2
  j <- i to 0 by -1
} yield (i, j)
//res: IndexedSeq[(Int, Int)] = Vector((1,1), (1,0), (2,2), (2,1), (2,0))
Run Code Online (Sandbox Code Playgroud)