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.
This looks like a combination of several problems.
1 until 5
returns ascala.collection.immutable.Range
, while1 to 5
returnsRange.Inclusive
.Range.Inclusive
is a concrete class, andscala.collection.immutable.Range
is the parent of bothRange.Inclusive
andRange.Exclusive
. It looks as though due to the open bug Leo C mentioned,scala.collection.immutable.Range
considered onlyAbstractSeq
rather thanIndexedSeq
(as Silvio Mayolo's comment suggested). AndAbstractSeq
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 thatAbstractSeq
isabstract
, butIndexedSeq
is a trait as well. That said, it is probably by design thatAbstractSeq
cannot be constructed, but IndexedSeq can.