3

I'm new to Scala and coming at this from an imperative background but I'd like to understand it in functional terms. I'm very confused about the behavior of the following code snippets.

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

println(s"res is $res")

This code will print res is Vector((1,1), (1,2), (2,1), (2,2)) as expected. However modifying the above slightly to

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

println(s"res is $res")

prints res is Vector()

Why doesn't the second version of the loop yield Vector((1,1), (1,0), (2,2), (2,1), (2,0))?

This behavior has a significant impact on my ability to loop over 2D matrices using indices in Scala. In general, how could one loop over ONLY the upper triangular portion of a matrix in an idiomatic way while keeping track of the row and column indices?

1

1 Answer 1

6

Let the REPL tell you.

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

A Range won't go downward unless you tell it to.

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))
Sign up to request clarification or add additional context in comments.

1 Comment

Tyvm the sidebar helped me realize this as well. For those who need more info: On ranges: stackoverflow.com/questions/2617513/… On Upper-triangular idioms: stackoverflow.com/questions/18707121/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.