Writing a generic function that can take a Writer as well as an OutputStream
- by ebruchez
I wrote a couple of functions that look like this:
def myWrite(os: OutputStream) = {}
def myWrite(w: Writer) = {}
Now both are very similar and I thought I would try to write a single parametrized version of the function.
I started with a type with the two methods that are common in the Java OutputStream and Writer:
type Writable[T] = {
def close() : Unit
def write(cbuf: Array[T], off: Int, len: Int): Unit
}
One issue is that OutputStream writes Byte and Writer writes Char, so I parametrized the type with T.
Then I write my function:
def myWrite[T, A[T] <: Writable[T]](out: A[T]) = {}
and try to use it:
val w = new java.io.StringWriter()
myWrite(w)
Result:
<console>:9: error: type mismatch;
found : java.io.StringWriter
required: ?A[ ?T ]
Note that implicit conversions are not applicable because they are ambiguous:
both method any2ArrowAssoc in object Predef of type [A](x: A)ArrowAssoc[A]
and method any2Ensuring in object Predef of type [A](x: A)Ensuring[A]
are possible conversion functions from java.io.StringWriter to ?A[ ?T ]
myWrite(w)
I tried a few other combinations of types and parameters, to no avail so far.
My question is whether there is a way of achieving this at all, and if so how.
(Note that the implementation of myWrite will need, internally, to know the type T that parametrizes the write() method, because it needs to create a buffer as in new ArrayT.)