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

How does a for loop with multiple generators work in Scala?

我是 Scala 的新手,从命令式的背景开始接触这个,但我想从功能的角度来理解它。我对以下代码片段的行为感到非常困惑。

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

println(s"res is $res")

此代码将按预期打印 res is 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")

打印 res 是 Vector()

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

这种行为对我在 Scala 中使用索引循环二维矩阵的能力产生了重大影响。通常,如何在跟踪行和列索引的同时以惯用的方式仅遍历矩阵的上三角部分?

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

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

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