Why can I use `to` in the first argument of Future.traverse, but not `until`?

134 Views Asked by At

Why can I use to to construct a Range for the first argument of Future.traverse, but not until? See the following example Scala console interaction.

scala> Future.traverse(1 to 5)(Future.successful)
val res5: scala.concurrent.Future[IndexedSeq[Int]] = Future(<not completed>)

scala> Future.traverse(1 until 5)(Future.successful)
                                 ^
       error: Cannot construct a collection of type scala.collection.immutable.AbstractSeq[Int] with elements of type Int based on a collection of type scala.collection.immutable.AbstractSeq[Int].

scala> res5
val res7: scala.concurrent.Future[IndexedSeq[Int]] = Future(Success(Vector(1, 2, 3, 4, 5)))

scala>

Note that I'm using Scala 2.13.5 for the console though Scala 2.13.2 seems to have the same behavior.

For what it's worth, I noticed that to returns Range.Inclusive, and until returns Range.Exclusive. But both extend Range, so I'm at a loss as to what is different between these two types such that Future.traverse can take one but not the other as the first argument.

1

There are 1 best solutions below

0
On BEST ANSWER

This looks like a combination of several problems.

1 until 5 returns a scala.collection.immutable.Range, while 1 to 5 returns Range.Inclusive.

scala> val exclusive: Range.Exclusive = 1 until 5
                                          ^
       error: type mismatch;
        found   : scala.collection.immutable.Range
        required: Range.Exclusive

scala> val inclusive: Range.Inclusive = 1 to 5
val inclusive: Range.Inclusive = Range 1 to 5

Range.Inclusive is a concrete class, and scala.collection.immutable.Range is the parent of both Range.Inclusive and Range.Exclusive. It looks as though due to the open bug Leo C mentioned, scala.collection.immutable.Range considered only AbstractSeq rather than IndexedSeq (as Silvio Mayolo's comment suggested). And AbstractSeq cannot be constructed. Range.Inclusive, being a concrete class, does not have the same problem.

I am not sure at this point why AbstractSeq cannot be constructed. I had thought the reason was that AbstractSeq is abstract, but IndexedSeq is a trait as well. That said, it is probably by design that AbstractSeq cannot be constructed, but IndexedSeq can.