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