2011-11-11 28 views
6

Me preguntaba si hay una mejor manera de escribir bucles recursivos en scala.Cómo hacer bucles recursivos en 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() 
} 

podría escribir como este

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

pero entonces ayb estaría expuesto y no encapsulado dentro del método más.

+0

Así es como se hace (el primer ejemplo). El 'def 'interno también asegura que es privado y puede optimizarse para cañas de cola. – huynhjl

+0

La segunda versión es recursiva de cola también. Le pregunté sobre la posibilidad de agregar alguna forma de hacer que estos parámetros fueran privados de la lista de correo de Scala Language en agosto y se encontró con un silencio ensordecedor/falta de interés. http://www.scala-lang.org/node/10736 –

+0

Respuesta corta: No. –

Respuesta

3

Tenga en cuenta que a menudo se puede utilizar foldLeft o foldRight en tales situaciones:

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

[Editar]

Otro enfoque sería una solución basada en el iterador:

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

Esto genera una cantidad infinita de números de Fibonacci, pero simplemente puede tomar todos los que desee él, e.g. fib.take(10).toList

1

Los bucles tienen su propio alcance. Cuando reemplaza un bucle con una función recursiva, se ve obligado a crear un alcance explícito (el método interno). No hay manera de evitarlo. Así es como se hace. No hay nada de malo en eso

Cuestiones relacionadas