2010-11-01 5 views
1

J'essaye d'implémenter une fonction numérotée de nombre de Fibonacci, et je cours dans une erreur de compilation que je ne peux pas trier. Le code suivant est ce que j'ai jusqu'ici.Erreur de compilation Scala récursive fermeture

var fibs = Map.empty[Int, Int] 
fibs += 0 -> 1 
fibs += 1 -> 1 
fibs += 2 -> 2 
val fib = (n: Int) => { 
    if (fibs.contains(n)) return fibs.apply(n) 
    else{ 
    // Error here 
    val result = fib(n - 1) + fib(n - 2) 
    fibs+= n -> result 
    return result 
    } 
} 
println(fib(100)) 

L'erreur est:

récursives fib besoins de type

J'ai essayé d'entrer un type de retour pour la fermeture en divers endroits, mais je ne peux pas sembler l'obtenir travailler.

Déclarer la fermeture comme val fib = (n: Int): Int => { donne une erreur de compilation différente.

Pourriez-vous s'il vous plaît m'aider à corriger cette erreur de compilation?

Répondre

3

Vous devez définir explicitement le type de retour des fonctions récursives. Il ne peut pas déduire le type parce que l'inférence serait cyclique. Donc: def fib (n: Int): Int = ...

+0

Déclarant la fermeture comme 'val = fib (n: Int): Int => {' donne une erreur de compilation différente. – jjnguy

+0

Aussi, merci pour l'entrée. – jjnguy

+2

Je vous ai donné la syntaxe 'def'. Si vous voulez utiliser 'val' pour définir la fonction, vous devez lui donner un type comme vous le feriez normalement:' val fib: (Int => Int) = (n: Int) => {...} ' –

5

Vous pouvez définir une méthode comme suggéré par Ben Jackson (c'est-à-dire def fib (n: Int): Int = ...).

Les valeurs de fonction ne peuvent pas être récursives. EDIT: Il s'avère they can be recursive; vous avez juste besoin d'aider l'inferenceur de type un peu plus. En outre, vous devez vous débarrasser de return; il ne peut être utilisé dans les méthodes.

Les travaux suivants:

var fibs = Map.empty[Int, Int] 
fibs += 0 -> 1 
fibs += 1 -> 1 
fibs += 2 -> 2 
val fib: (Int => Int) = n => { 
    if(fibs contains n) 
    fibs(n) 
    else { 
    val result = fib(n - 1) + fib(n - 2) 
    fibs += n -> result 
    result 
    } 
} 
println(fib(100)) 

Aussi, vous devriez jeter un oeil à this blogpost pour comprendre comment vous pouvez abstraire la logique memoization avec l'aide de lambdas.

+0

Voir aussi http://stackoverflow.com/questions/3640823/in-scala-2-8-what-type-to-use-to-store-an-in-memory-mutable-data-table –

+0

Merci pour la mise à jour . – jjnguy

1

Débarrassez-vous de la return, car ils ne peuvent être utilisés avec def, non val et déclarer le type de fib, comme c'est une exigence Scala pour les définitions récursives.

val fib: (Int => Int) = (n: Int) => { 
    if (fibs.contains(n)) fibs.apply(n) 
    else{ 
    val result = fib(n - 1) + fib(n - 2) 
    fibs+= n -> result 
    result 
    } 
} 

Notez que fib(100) débordera un Int

+0

Cela ressemble exactement à ce dont j'ai besoin, merci. – jjnguy