scala - tipos - ¿Cuándo se evalúa exactamente la cabeza de un arroyo?
tipos de evaluacion del aprendizaje (2)
La cabeza se evalúa en el momento en que se crea la secuencia.
Pero en su segundo ejemplo, no pasa un Streem como segundo argumento a #::
usted pasa un parámetro por nombre, es decir, la expresión completa Stream( {println("evaluating 1"); 1} , 2, 3)
isn no evaluado en absoluto.
Normalmente, si crea un objeto Stream
, la cabeza se evaluará ansiosamente:
scala> Stream( {println("evaluating 1"); 1} , 2, 3)
evaluating 1
res63: scala.collection.immutable.Stream[Int] = Stream(1, ?)
Si creamos una secuencia a la que precedamos en la misma declaración, parece ligeramente sorprendente que la cabeza no se evalúe antes de la concatenación. es decir
scala> 0 #:: Stream( {println("evaluating 1"); 1} , 2, 3)
res65: scala.collection.immutable.Stream[Int] = Stream(0, ?)
( #::
tiene una asociación correcta y es el método ConsWrapper
a ConsWrapper
, que es una clase implícita de Stream
).
¿Cómo esto no evalúa su cabeza antes de anteponer el 0? ¿Es que la cola Stream (o cons cell) no existe en el montón hasta que tomemos valores de la secuencia resultante? Pero si es así, ¿cómo llamamos al método #::
en un objeto que aún no existe?
-Xprint:typer
es tu amigo, cada vez que quieras entender exactamente cómo se evalúa algún código o se deducen tipos.
scala -Xprint:typer -e ''0 #:: Stream( {println("evaluating 1"); 1} , 2, 3)''
val x$1: Int = 0;
Stream.consWrapper[Int](Stream.apply[Int]({
println("evaluating 1");
1
}, 2, 3)).#::(x$1)
El parámetro de consWrapper
es por nombre. Entonces, incluso esto funciona:
scala> (1 #:: (sys.error("!!"): Stream[Int])).head
res1: Int = 1