Skip to content

Commit 8b3c015

Browse files
committed
Merge pull request #775 from mikejcurry/add-stream-show
Adds Show[Stream]
2 parents 971f954 + 7e7ca84 commit 8b3c015

2 files changed

Lines changed: 28 additions & 0 deletions

File tree

core/src/main/scala/cats/std/stream.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cats
22
package std
33

44
import scala.collection.immutable.Stream.Empty
5+
import cats.syntax.show._
56

67
trait StreamInstances {
78
implicit val streamInstance: Traverse[Stream] with MonadCombine[Stream] with CoflatMap[Stream] =
@@ -58,6 +59,11 @@ trait StreamInstances {
5859
override def isEmpty[A](fa: Stream[A]): Boolean = fa.isEmpty
5960
}
6061

62+
implicit def streamShow[A: Show]: Show[Stream[A]] =
63+
new Show[Stream[A]] {
64+
def show(fa: Stream[A]): String = if(fa.isEmpty) "Stream()" else s"Stream(${fa.head.show}, ?)"
65+
}
66+
6167
// TODO: eventually use algebra's instances (which will deal with
6268
// implicit priority between Eq/PartialOrder/Order).
6369

tests/src/test/scala/cats/tests/StreamTests.scala

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,26 @@ class StreamTests extends CatsSuite {
1616

1717
checkAll("Stream[Int] with Option", TraverseTests[Stream].traverse[Int, Int, Int, List[Int], Option, Option])
1818
checkAll("Traverse[Stream]", SerializableTests.serializable(Traverse[Stream]))
19+
20+
test("show") {
21+
Stream(1, 2, 3).show should === ("Stream(1, ?)")
22+
Stream.empty[Int].show should === ("Stream()")
23+
}
24+
25+
test("Show[Stream] is referentially transparent, unlike Stream.toString") {
26+
forAll { stream: Stream[Int] =>
27+
if (!stream.isEmpty) {
28+
val unevaluatedStream = stream map identity
29+
val initialShow = unevaluatedStream.show
30+
31+
// Evaluating the tail can cause Stream.toString to return different values,
32+
// depending on the internal state of the Stream. Show[Stream] should return
33+
// consistent values independent of internal state.
34+
unevaluatedStream.tail
35+
initialShow should === (unevaluatedStream.show)
36+
} else {
37+
stream.show should === (stream.toString)
38+
}
39+
}
40+
}
1941
}

0 commit comments

Comments
 (0)