Scala递归闭包编译错误

时间:2010-11-01 03:42:36

标签: scala recursion closures

我正在尝试实现一个memoized Fibonacci数字函数,我遇到了一个我无法解决的编译错误。以下代码是我目前所拥有的。

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))

错误是:

  

递归fib需要输入

我已经尝试在不同的地方输入闭包的返回类型,但我似乎无法让它工作。

声明像val fib = (n: Int): Int => {这样的闭包会产生不同的编译错误。

你能帮我解决这个编译错误吗?

3 个答案:

答案 0 :(得分:5)

您可以按照Ben Jackson的建议定义一种方法(即def fib (n: Int): Int = ...)。

函数值不能递归。编辑:结果是they can be recursive;你只需要更多地帮助类型推理器。此外,你需要摆脱return;它只能用在方法中。

以下作品:

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))

另外你应该看看this blogpost,了解如何借助lambdas抽象出记忆逻辑。

答案 1 :(得分:3)

您必须显式设置递归函数的返回类型。它无法推断出类型,因为推理是循环的。所以:def fib (n: Int): Int = ...

答案 2 :(得分:1)

删除return,因为它们只能与def一起使用,而不能与val一起使用,并声明fib的类型,因为这是Scala的要求递归定义。

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
  }
}

请注意,fib(100)会溢出Int