Skip to content

Commit

Permalink
Merge pull request #665 from non/bug/fix-memoize
Browse files Browse the repository at this point in the history
Fix Streaming#memoization.
  • Loading branch information
ceedubs committed Nov 19, 2015
2 parents 987727c + 8ed18f5 commit 3061c8f
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 4 deletions.
15 changes: 11 additions & 4 deletions core/src/main/scala/cats/data/Streaming.scala
Original file line number Diff line number Diff line change
Expand Up @@ -642,14 +642,21 @@ sealed abstract class Streaming[A] extends Product with Serializable { lhs =>
* Ensure that repeated traversals of the stream will not cause
* repeated tail computations.
*
* By default stream does not memoize to avoid memory leaks when the
* head of the stream is retained.
* By default this structure does not memoize to avoid memory leaks
* when the head of the stream is retained. However, the user
* ultimately has control of the memoization approach based on what
* kinds of Eval instances they use.
*
* There are two calls to .memoize here -- one is a recursive call
* to this method (on the tail) and the other is a call to memoize
* the Eval instance holding the tail. For more information on how
* this works see [[cats.Eval.memoize]].
*/
def memoize: Streaming[A] =
this match {
case Empty() => Empty()
case Wait(lt) => Wait(lt.memoize)
case Cons(a, lt) => Cons(a, lt.memoize)
case Wait(lt) => Wait(lt.map(_.memoize).memoize)
case Cons(a, lt) => Cons(a, lt.map(_.memoize).memoize)
}

/**
Expand Down
18 changes: 18 additions & 0 deletions tests/src/test/scala/cats/tests/StreamingTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,24 @@ class StreamingTests extends CatsSuite {

class AdHocStreamingTests extends CatsSuite {

test("results aren't reevaluated after memoize") {
forAll { (orig: Streaming[Int]) =>
val ns = orig.toList
val size = ns.size

var i = 0
val memoized = orig.map { n => i += 1; n }.memoize

val xs = memoized.toList
i should === (size)
xs should === (ns)

val ys = memoized.toList
i should === (size)
ys should === (ns)
}
}

test("fromList/toList") {
forAll { (xs: List[Int]) =>
Streaming.fromList(xs).toList should === (xs)
Expand Down

0 comments on commit 3061c8f

Please sign in to comment.