Как реализовать рекурсивную последовательность Фибоначчи в Scala с использованием FS2?

Пытаясь ознакомиться с FS2, я наткнулся на изящную рекурсивную реализацию, использующую поток коллекций Scala, и подумал, что мне стоит попробовать ее в 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, и каков наилучший способ получить подобное, рабочее решение?

1 ответ

Решение

Ваша проблема в том, что Stream.fold потребляет все элементы потока, производя единственное окончательное значение из сгиба. Обратите внимание, что он излучает только один элемент.

Рекурсивный поток заканчивается только тогда, когда испущено 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)
Другие вопросы по тегам