2011-12-15 17 views
5

Esecuzione:Scala flusso confusione

lazy val s: Stream[Int] = 1 #:: 2 #:: {val x = s.tail.map(_+1); println("> " + x.head); x} 
s.take(5).toList 

mi aspetto:

> List(2, 3) 
> List(2, 3, 4) 
List(1, 2, 3, 4, 5) 

e ottengo:

> 3 
List(1, 2, 3, 4, 5) 

Potrebbe spiegare a me?

+2

Perché dovresti aspettarti che 'x.head' restituisca una lista? – sepp2k

+0

Ciò che mi confonde è il motivo per cui vorresti inserire un 'println' nella definizione di un valore pigro. –

+2

@Dan: Immagino quando e quanto spesso verrà eseguita l'espressione (e quali saranno i vari valori quando lo farà). – sepp2k

risposta

5

La ragione per cui si sta ottenendo uno Int anziché List è che s è un flusso di numeri interi, quindi contiene numeri interi, non elenchi.

Il motivo per cui ottieni 3 è che la coda di (1,2,3,4,5, ...) (ovvero s) è (2,3,4,5, ...) e se mappa +1 su di esso, otterrai (3,4,5,6,7, ...) e il titolo è 3.

Il motivo per cui viene stampato un solo numero intero è che l'espressione è valutato solo una volta per ottenere il flusso per la coda. Successivamente viene valutato solo lo stream restituito da s.tail.map(_+1) (che non contiene dichiarazioni di stampa).

+0

considera questo: 'val s: Stream [Int] = 1 # :: 2 # :: {val x = s.tail.map (1+); x prendere 10 stampe; x} 'stamperà' 3333 ... 'e cadrà, quindi' x' sembra essere un flusso di tre, non 3,4,5, ... ma non ha senso perché allora 's' dovrebbe essere un' stream (1,2,3,3,3, ...) '. Sono così confuso, qualche consiglio, dove posso leggere di più sui flussi? – 4e6

+0

@ 4e6: Consumare più elementi di uno stream di quanti siano stati generati ancora all'interno dell'espressione che genera lo stream, causerà una ricorsione infinita (che alla fine farà esplodere lo stack). Il motivo per cui si ottengono così tanti 3s non è che il flusso contenga molti 3s (se lo facessero sarebbero separati da virgole), ma che l'istruzione print è eseguita tante volte (perché la logica ricorre nelle cerchie e arriva a la dichiarazione di stampa ancora e ancora e ancora ...). – sepp2k

+0

@ 4e6 Considera cosa hai scritto: per calcolare il terzo numero, è necessario stampare i primi 10 numeri. Ma come può stampare il terzo numero se non lo ha ancora calcolato? Sei tu che ottieni un errore. –