Dalla progettazione delle collezioni di Scala capisco che qualcosa di simile:La deforestazione in collezioni Scala
scala> BitSet(1,2,3) map (_ + "a")
res7: scala.collection.immutable.Set[String] = Set(1a, 2a, 3a)
Non si costruisce un datastructure intermedio: il nuovo set è costruito come il BitSet viene iterato rispetto all'uso di un cantiere. In questo caso, infatti, è ovvio dato che un insieme di stringhe non ha senso.
E le mappe dalle liste? Sono abbastanza sicuro che il seguente costruisce una lista intermedia:
scala> List(1,2,3) map (_ -> "foo") toMap
res8: scala.collection.immutable.Map[Int,java.lang.String] =
Map(1 -> foo, 2 -> foo, 3 -> foo)
vale a dire l'elenco List((1,foo), (2,foo), (3,foo))
. Se no, allora come? Ora, per quanto riguarda i seguenti?
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)
Questa volta, da quello che mi sembra di capire dal tipo di ++
:
def ++ [B >: (A, B), That]
(that: TraversableOnce[B])
(implicit bf: CanBuildFrom[Map[A, B], B, That]): That
ho penso potrebbe essere il caso che la mappa è costruito al volo, e che nessun la lista intermedia è costruita
È il caso? Se sì, è questo il modo canonico per garantire la deforestazione o esiste una sintassi più semplice?
Wow, ci sono voluti veramente 542 tentativi per farlo bene ;-) –
Grazie, questo è esattamente quello che stavo cercando. Quello di cui non sono sicuro è perché scala si lamenta di 'List ((3, 4), (9, 11)). Map (_. Swap): Map [Int, Int]' invece di usare il vincolo di tipo che ho esplicitamente messo a scegliere il giusto implicito (esattamente come read sceglie l'istanza di typeclass giusta in haskell a seconda del contesto). È solo che implicito non funziona in questo modo (lo comprenderei completamente, so che sottotitolare rende tutto difficile) o ho trascurato qualcosa in quel caso speciale? –
@DuncanMcGregor: non ho chiuso il REPL dagli ultimi 5 giorni. Lo uso pesantemente nel mio sviluppo quotidiano. :-) – missingfaktor