Writing a generic function that can take a Writer as well as an OutputStream

Posted by ebruchez on Stack Overflow See other posts from Stack Overflow or by ebruchez
Published on 2011-01-15T23:03:03Z Indexed on 2011/01/16 12:53 UTC
Read the original article Hit count: 155

Filed under:

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.)

© Stack Overflow or respective owner

Related posts about scala