Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement a recursive Fibonacci sequence in Scala using FS2?

Tags:

stream

scala

fs2

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?

like image 542
bbarker Avatar asked Sep 09 '16 17:09

bbarker


People also ask

How do you implement Fibonacci in Scala?

Another way of implementing Fibonacci is to define the sequence to be stored in a “lazy” collection, such as a Scala Stream: Using method scan, scan (1) (_ + _) generates a Stream with each of its elements being successively assigned the sum of the previous two elements.

How do you do a Fibonacci sequence in C with recursion?

Fibonacci Series in C Using Recursion Declare three variables as 0, 1, and 0 accordingly for a, b, and total. With the first term, second term, and the current sum of the Fibonacci sequence, use the fib() method repeatedly.

What is the Fibonacci sequence in JavaScript?

The Fibonacci sequence is a collection of numbers where a number is the sum of the previous two terms. Fibonacci sequence always starts from 0 and 1: Finding the Fibonacci number at the nth term using recursion is one of the most common coding interview problems that you may find, so let’s see how you can solve it in JavaScript.

How to calculate the Fibonacci number in Python?

The method fib () calculates the fibonacci number at position n. If n is equal to 0 or 1, it returns n. Otherwise it recursively calls itself and returns fib (n - 1) + fib (n - 2).


1 Answers

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)
like image 75
Gary Coady Avatar answered Nov 15 '22 03:11

Gary Coady