2011-11-11 15 views
6

Mi chiedevo se esiste un modo migliore per scrivere loop ricorsivi in ​​scala.Come fare loop ricorsivi in ​​scala

def fib(n: Int) = { 
    def loop(a: BigInt = 0, b: BigInt = 1, n: Int = n): BigInt = { 
    if(n==0) a 
    else loop(b, a+b, n-1) 
    } 
    loop() 
} 

Potrei scrivere in questo modo

def fib(n: Int, a: BigInt = 0, b: BigInt = 1): BigInt = { 
    if(n==0) a 
    else fib(n-1, b, a+b) 
} 

ma poi A e B sarebbe esposto e non incapsulato all'interno del metodo più.

+0

Questo è praticamente come è stato fatto (il primo esempio). Il 'def' interno garantisce anche che sia privato e possa essere ottimizzato per le code di coda. – huynhjl

+0

Anche la seconda versione è a coda ricorsiva. Ho chiesto la possibilità di aggiungere un modo per rendere questi parametri privati ​​della mailing list della lingua di Scala in agosto e sono stati accolti da un silenzio assordante/mancanza di interesse. http://www.scala-lang.org/node/10736 –

+0

Risposta breve: No. –

risposta

3

Nota che spesso è possibile utilizzare foldLeft o foldRight in tali situazioni:

def fib(n: Int) = (1 to n).foldLeft((BigInt(0),BigInt(1)))((p,_)=>(p._2,p._1+p._2))._1 

[Edit]

Un altro approccio sarebbe una soluzione iteratore-based:

def fib = Iterator.iterate((0,1)){case (x,y) => (y,x+y)}.map(_._1) 

Questo genera una quantità infinita di numeri di Fibonacci, ma puoi semplicemente prenderne quanti ne desideri ad es. fib.take(10).toList

1

I loop hanno i propri scopi. Quando si sostituisce un ciclo con una funzione ricorsiva, si è costretti a creare un ambito esplicito (il metodo interno). Non c'è modo di aggirarlo. Questo è come è fatto. Niente di sbagliato in proposito.