I'm currently writing some code using ad-hoc polymorphism in Scala.
For example, one of my classes extends a Stream[Boolean]
with a method:
implicit class BooleanStreamOps(s: Stream[Boolean]) {
def toByteStream: Stream[Byte] = ???
// ...
}
Now so far this is good, but when the stream gets printed (for example by specs2) it will print the whole stream, if it was already evaluated, spamming the output of the console.
Now I am trying to overwrite toString, but I imagine I'll have to create an extra class for that which holds the Stream, like so:
final case class BooleanStream(unwrap: Stream[Boolean]) {
override def toString: String = s"Stream(${unwrap.size})"
}
implicit class BooleanStreamOps(s: BooleanStream) {
def toByteStream: Stream[Byte] = ???
}
This has the nice effect that users of the library who also use Stream[Boolean] will not accidentally call one of my methods. The downside is, that whenever I use the actual stream I have to call unwrap on the object, which clutters the code quite a bit.
I think my options are these:
- Teach specs2 to use cats' Show[T] instead of using toString - Is it possible? I've seen there is a package specs2-cats - but I can't seem to find it for scala 2.12.
- Do as noted above, use unwrap on every usage of the stream
Which of the above options do you think work best my case?
Non-options:
- Extend my own class from Stream - it's sealed for good reason
- Write all methods of stream mapping to unwrap - too much effort IMO