Desde el diseño de colecciones de Scala entiendo que algo como:La deforestación en colecciones Scala
scala> BitSet(1,2,3) map (_ + "a")
res7: scala.collection.immutable.Set[String] = Set(1a, 2a, 3a)
no construye una estructura de datos intermedia: El nuevo conjunto se construye como el BitSet se itera sobre el uso de un constructor. De hecho, en ese caso es obvio ya que un conjunto de bits de cadenas no tiene sentido.
¿Qué pasa con los mapas de las listas? Estoy bastante seguro de que el siguiente construye 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)
saber, la lista List((1,foo), (2,foo), (3,foo))
. Si no, ¿cómo? Ahora, ¿qué hay de lo siguiente?
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)
Esta vez, por lo que parece entender el tipo de ++
:
def ++ [B >: (A, B), That]
(that: TraversableOnce[B])
(implicit bf: CanBuildFrom[Map[A, B], B, That]): That
I piensan que podría darse el caso de que el mapa se construye sobre la marcha, y que ningún lista intermedia está construida.
¿Es el caso? En caso afirmativo, ¿es esta la forma canónica de garantizar la deforestación o existe una sintaxis más directa?
Wow, realmente tomó 542 intentos para hacerlo bien ;-) –
Gracias, esto es exactamente lo que estaba buscando. De lo que no estoy seguro es de por qué Scala se queja de 'List ((3, 4), (9, 11)). Map (_. Swap): Map [Int, Int]' en lugar de usar la restricción de tipo que tengo explique explícitamente el derecho implícito (exactamente como lee elige la instancia correcta de clase de tipo en haskell dependiendo del contexto). ¿Es solo que lo implícito no funciona de esa manera (lo entendería totalmente, sé que la subtipificación hace que todo sea difícil) o pasé por alto algo en ese caso especial? –
@DuncanMcGregor: No he cerrado el REPL desde hace 5 días. Lo uso mucho en mi desarrollo diario. :-) – missingfaktor