【问题标题】:Tracing execution of calculation of Fibonacci using Scala Streams使用 Scala Streams 跟踪斐波那契计算的执行
【发布时间】:2014-01-20 11:20:11
【问题描述】:

我是函数式编程/scala 新手。我一直在努力理解以下代码 sn-p 并生成输出。

def fib:Stream[Int] = {
  Stream.cons(1,
    Stream.cons(2,
      (fib zip fib.tail) map {case (x, y) => println("%s + %s".format(x, y)); x + y}))
}

输出跟踪:

scala> fib take 4 foreach println

1
2
1 + 2
3
1 + 2  <-- Why this ?????
2 + 3
5

我不明白如何评估 1 + 2 以计算结果 5。 理论上,我确实理解 def 应该强制重新计算 fib 但我无法找到执行跟踪中可能发生这种情况的位置。

我想告诉你们我的理解

Output( My understanding):

1  
This is the head, trivial

2  
This is the tail of the first Cons in Cons( 1, Cons( 2, fn ) ). Trivial.

1 + 2
(fib zip fib.tail) map {case (x, y) => println("%s + %s".format(x, y)); x + y}))
first element of fib is 1
first element of fib.tail is 2
Hence 1 + 2 is printed.

The zip operation on the Stream does the following
 Cons( ( this.head, that.head), this.tail zip that.tail ) # this is fib and that is fib.tail. Also remember that this.tail starts from 2 and that.tail would start from 3. This new Stream forms an input to the map operation.

The map operation does the following 
cons(f(head), tail map f ) # In this case tail is a stream defined in the previous step and it's not evaluated.

So, in the next iteration when tail map f is evaluated shouldn't just 2 + 3 be printed ? I don't understand why 1 + 2 is first printed 

:( :( :(

我有什么明显的遗漏吗?

【问题讨论】:

  • 如果把def改成val,好像没有第二个1+2;
  • 这似乎是this question的副本

标签: scala stream lazy-evaluation fibonacci


【解决方案1】:

https://stackoverflow.com/a/20737241/3189923 中提出的斐波那契编码,此处添加了详细信息以跟踪执行,

val fibs: Stream[Int] = 0 #:: fibs.scanLeft(1)((a,b) => {
  println(s"$a + $b = ${a+b}")
  a+b
})

然后,例如,

scala> fibs(7)
1 + 0 = 1
1 + 1 = 2
2 + 1 = 3
3 + 2 = 5
5 + 3 = 8
8 + 5 = 13
res38: Int = 13

【讨论】:

    猜你喜欢
    • 2013-03-31
    • 2020-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-18
    • 2015-05-23
    • 2016-09-01
    • 2012-12-03
    相关资源
    最近更新 更多