Skip to content

Commit

Permalink
fix #2940 (#2942)
Browse files Browse the repository at this point in the history
  • Loading branch information
road21 authored and LukaJCB committed Jul 12, 2019
1 parent 07b2c21 commit e131e53
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 1 deletion.
2 changes: 1 addition & 1 deletion free/src/main/scala/cats/free/Cofree.scala
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ object Cofree extends CofreeInstances {
* A stack-safe algebraic recursive fold out of the cofree comonad.
*/
def cata[F[_], A, B](cof: Cofree[F, A])(folder: (A, F[B]) => Eval[B])(implicit F: Traverse[F]): Eval[B] =
F.traverse(cof.tailForced)(cata(_)(folder)).flatMap(folder(cof.head, _))
F.traverse(cof.tailForced)(c => Eval.defer(cata(c)(folder))).flatMap(folder(cof.head, _))

/**
* A monadic recursive fold out of the cofree comonad into a monad which can express Eval's stack-safety.
Expand Down
13 changes: 13 additions & 0 deletions free/src/test/scala/cats/free/CofreeSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,19 @@ class CofreeSuite extends CatsSuite {
cata should ===(nelUnfoldedHundred)
}

test("Cofree.cata is stack-safe") {
val unfolded = Cofree.unfold[Option, Int](0)(i => if (i == 50000) None else Some(i + 1))
val sum = List.tabulate(50000)(identity).sum
val cata =
Cofree
.cata[Option, Int, Int](unfolded)(
(i, lb) => Eval.now(lb.fold(0)(_ + i))
)
.value

cata should ===(sum)
}

test("Cofree.cataM") {

type EvalOption[A] = OptionT[Eval, A]
Expand Down

0 comments on commit e131e53

Please sign in to comment.