5

While trying to become familiar with FS2, I came across a nifty recursive implementation using the Scala collections' Stream, and thought I'd have a go at trying it in 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

What is the reason this hangs in FS2, and what is the best way to get a similar, working solution?

Community
  • 1
  • 1
bbarker
  • 11,636
  • 9
  • 38
  • 62

1 Answers1

8

Your issue is that Stream.fold consumes all elements of the stream, producing a single final value from the fold. Note that it only emits one element.

The recursive stream only terminates when 10 elements have been emitted (this is specified by take 10). Since this stream is not productive enough, fold continues to add values without stopping.

The simplest way to fix this is to use a combinator that emits the partial results from the fold; this is scan.

Also, FS2 can infer most of the types in this code, so you don't necessarily need as many type annotations.

The following implementation should work fine:

import fs2.{Pure, Stream}
val fibs: Stream[Pure, Int] = Stream(0) ++ fibs.scan(1)(_ + _)
println(fibs take 10 toList)
Gary Coady
  • 1,196
  • 9
  • 13
  • Ugh, actually started with trying scan, but had some syntax issues and switched to fold. At least I learned the difference between fold and scan... – bbarker Sep 09 '16 at 18:03
  • More info for the functionally unadept: http://stackoverflow.com/a/17408881/3096687 – bbarker Sep 09 '16 at 18:12