如何使用 FS2 在 Scala 中实现递归斐波那契数列?
How to implement a recursive Fibonacci sequence in Scala using FS2?
在尝试熟悉 FS2 时,我发现 nifty recursive implementation 使用 Scala 集合的 Stream,我想我可以尝试在 FS2 中尝试它:
import fs2.{Pure, Stream}
val fibs: Stream[Pure, Int] = Stream[Pure, Int](0) ++ fibs.fold[Int](1)(_ + _)
println(fibs take 10 toList) // This will hang
这在 FS2 中挂起的原因是什么?获得类似的有效解决方案的最佳方法是什么?
您的问题是 Stream.fold
消耗了流的所有元素,从折叠中产生了一个最终值。请注意,它仅发出 one 个元素。
递归流仅在发出 10 个元素时终止(这由 take 10
指定)。由于此流的生产效率不够高,fold
继续不停地增加价值。
解决此问题的最简单方法是使用组合器从折叠中发出部分结果;这是 scan
.
此外,FS2 可以推断出此代码中的大多数类型,因此您不一定需要那么多类型注释。
以下实现应该可以正常工作:
import fs2.{Pure, Stream}
val fibs: Stream[Pure, Int] = Stream(0) ++ fibs.scan(1)(_ + _)
println(fibs take 10 toList)
在尝试熟悉 FS2 时,我发现 nifty recursive implementation 使用 Scala 集合的 Stream,我想我可以尝试在 FS2 中尝试它:
import fs2.{Pure, Stream}
val fibs: Stream[Pure, Int] = Stream[Pure, Int](0) ++ fibs.fold[Int](1)(_ + _)
println(fibs take 10 toList) // This will hang
这在 FS2 中挂起的原因是什么?获得类似的有效解决方案的最佳方法是什么?
您的问题是 Stream.fold
消耗了流的所有元素,从折叠中产生了一个最终值。请注意,它仅发出 one 个元素。
递归流仅在发出 10 个元素时终止(这由 take 10
指定)。由于此流的生产效率不够高,fold
继续不停地增加价值。
解决此问题的最简单方法是使用组合器从折叠中发出部分结果;这是 scan
.
此外,FS2 可以推断出此代码中的大多数类型,因此您不一定需要那么多类型注释。
以下实现应该可以正常工作:
import fs2.{Pure, Stream}
val fibs: Stream[Pure, Int] = Stream(0) ++ fibs.scan(1)(_ + _)
println(fibs take 10 toList)