懒惰的斐波那契系列

时间:2014-11-28 14:17:10

标签: java c# scala haskell fibonacci

我刚刚开始学习haskell,并想知道我们是否可以在C#或java或其他非懒惰的命令式语言中实现斐波那契系列。

在haskell中,我们可以用下面的一个衬里简洁地生成斐波那契系列

  

fibonacci = 0:1:zipWith(+)fibonacci(tail fibonacci)

问题 - 我理解,随着C#/ Java等热切评估,上面可能会进入无限循环。但我不明白的是,即使我们使用thunk,我们怎样才能创建一个自引用数据结构,当我们迭代它时会发生变化(使用递归)

感谢您是否可以分享一些代码段

2 个答案:

答案 0 :(得分:1)

Scala API docs for Stream包含有关如何在Scala中执行此操作的示例:

val fibs: Stream[BigInt] = BigInt(0) #:: BigInt(1) #:: fibs.zip(fibs.tail).map { n => n._1 + n._2 }

编辑:要使用像Haskell一样没有内置语言的语言来实现memoization,你显然需要使用变异(数组或映射)。例如:

  val fib: Int => Int = {
    val m = ArrayBuffer(0, 1)

    x => if (x < m.size) m(x) else {
      println("Calculating " + x + "...")
      val r = fib(x - 2) + fib(x - 1)
      m += r
      r
    }
  }

这仍然可以被认为是纯函数,因为在单线程环境中没有可观察到的副作用(除了运行时性能)。

答案 1 :(得分:1)

在C#中,您可以通过以下方式实现此目的:

IEnumerable <int> Fibonacci() {
    var a = 0;
    var b = 1;
    while (true) {
        var t = b;
        yield return b = a + b;
        a = t;
    }
}