Non è sempre una definizione ricorsiva. Questo in realtà funziona e produce 1:
val a : Int = a + 1
println(a)
variabile a
si crea quando si digita val a: Int
, in modo da poter utilizzare nella definizione. Int
viene inizializzato su 0 per impostazione predefinita. Una classe sarà nullo.
Come sottolineato da @Chris, Stream accetta => Stream[A]
quindi vengono applicate altre regole, ma volevo spiegare il caso generale. L'idea è sempre la stessa, ma la variabile viene passata per nome, quindi rende ricorsivo il calcolo. Dato che è passato per nome, viene eseguito pigramente. Stream calcola ogni elemento uno per uno, quindi chiama ones
ogni volta che ha bisogno dell'elemento successivo, in modo che lo stesso elemento venga prodotto ancora una volta. Questo funziona:
val ones: Stream[Int] = Stream.cons(1, ones)
println((ones take 10).toList) // List(1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
Anche se si può fare flusso infinito facile: Stream.continually(1)
Aggiornamento Come @SethTisue sottolineato nei commenti Stream.continually
e Stream.cons
sono due approcci completamente diversi, con risultati molto diversi, perché cons
prende A
quando continually
prende =>A
, il che significa che lo strumento continually
si ricalcola ogni volta che viene memorizzato e che l'elemento lo memorizza, quando lo cons
può evitare di memorizzarlo n volte a meno che non lo si converta nell'altra struttura come List
. È necessario utilizzare continually
solo se è necessario generare valori diversi. Vedi il commento @SethTisue per dettagli ed esempi.
Tuttavia, è necessario specificare il tipo, come per le funzioni ricorsive.
E si può fare il primo esempio ricorsivo:
lazy val b: Int = b + 1
println(b)
Questo StackOverflow.
Allo stesso modo funzionano le funzioni ricorsive. Pensare a "ones" è una funzione a zero argomenti. –