universitaria tipos ser momentos los libro evaluacion estrategias ejemplos educativa debe como caracteristicas aula aprendizajes aprendizaje scala stream lazy-evaluation

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