1

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:

  1. 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.
  2. 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:

  1. Extend my own class from Stream - it's sealed for good reason
  2. Write all methods of stream mapping to unwrap - too much effort IMO
Timo
  • 920
  • 8
  • 23
  • 1
    1 if it's possible. By the way, i don't think this has anything to do type classes (other than `Show[...]` which is not really what the question is about). – Alvaro Carrasco Apr 17 '17 at 21:35
  • Thanks for the response! You're right, not in the above example - it's simplified. – Timo Apr 17 '17 at 22:07
  • 3
    Another option: `implicit def unwrap (bs: BooleanStream): Stream[Boolean] = bs.unwrap` defined in `BooleanStream`'s companion object. – Alvaro Carrasco Apr 17 '17 at 22:46
  • Or roll your own `Show[T]`. It's quite simple, follow: http://stackoverflow.com/questions/6939956/in-scala-is-it-possible-to-use-implicits-to-automatically-override-tostring – PH88 Apr 18 '17 at 03:58
  • @AlvaroCarrasco Oh yeah, nice trick! Thanks! – Timo Apr 18 '17 at 08:32
  • @PH88 I'm not sure that will help me. Even if I did, I belive the scala compiler will still use the original `toString` of `Stream` and not my implementation, right? – Timo Apr 18 '17 at 08:34
  • Sorry I misread your option 1. Thought you're only looking for a Show[T] implementation. – PH88 Apr 18 '17 at 10:07

0 Answers0