From the design of Scala's collections I understand that something like:
scala> BitSet(1,2,3) map (_ + "a")
res7: scala.collection.immutable.Set[String] = Set(1a, 2a, 3a)
doesn't build an intermediate datastructure: the new Set is built as the BitSet is iterated over using a Builder. In fact in that case it is obvious since a bitset of strings doesn't make sense.
What about maps from lists? I am pretty sure that the following builds an intermediate list:
scala> List(1,2,3) map (_ -> "foo") toMap
res8: scala.collection.immutable.Map[Int,java.lang.String] =
Map(1 -> foo, 2 -> foo, 3 -> foo)
namely the list List((1,foo), (2,foo), (3,foo))
. If not, then how? Now, what about the following?
scala> Map.empty ++ (List(1,2,3) map (_ -> "foo"))
res10: scala.collection.immutable.Map[Int,java.lang.String] =
Map(1 -> foo, 2 -> foo, 3 -> foo)
This time, from what I seem to understand from the type of ++
:
def ++ [B >: (A, B), That]
(that: TraversableOnce[B])
(implicit bf: CanBuildFrom[Map[A, B], B, That]): That
I think it might be the case that the map is built on the fly, and that no intermediate list is constructed.
Is it the case? If yes, is this the canonical way of ensuring deforestation or is there a more straightforward syntax?