This page is no longer maintained — Please continue to the home page at www.scala-lang.org

could not find implicit value for evidence parameter of type ...

No replies
Alf Kristian Støyle
Joined: 2009-09-19,
User offline. Last seen 2 years 38 weeks ago.

Hi all. Playing around with type classes, and getting a compile error:

[error] ResourceUtils.scala:70: could not find implicit value for
evidence parameter of type
ResourceUtils.this.Resource[java.io.BufferedInputStream]
[error] usingTwo(new BufferedInputStream(sourceStream), new
BufferedOutputStream(targetStream)) {

This is the code:

trait ResourceUtils {

trait Resource[R] {
def close(r: R): Unit
}

/*
implicit def genericResourceTrait[A <: { def close() }] = new Resource[A] {
override def close(a: A) = a.close()
}
*/

implicit object jioCloseableResourceTrait extends
Resource[java.io.Closeable] {
override def close(a: java.io.Closeable) = a.close()
}

implicit object sqlConnectionResource extends Resource[java.sql.Connection] {
override def close(a: java.sql.Connection) = a.close()
}

/**
* Handles close of resources for you correctly in a finally clause.
*/
def using[R: Resource, A]
(closeable: R)
(f: R => A) = {
try {
f(closeable)
} finally {
if (closeable != null) {
try {
implicitly[Resource[R]].close(closeable)
}
catch {
case e: Exception => println("Exception on close", e)
}
}
}
}

def usingTwo[R: Resource, U: Resource, A]
(closeableOne: R, closeableTwo: U)
(f: (R, U) => A): A = {
using(closeableOne) {
_ =>
using(closeableTwo) {
_ =>
f(closeableOne, closeableTwo)
}
}
}

def pipeStreams(sourceStream: InputStream, targetStream: OutputStream) {
usingTwo(new BufferedInputStream(sourceStream), new
BufferedOutputStream(targetStream)) {
(input, output) =>
var value = input.read()
while (value != -1) {
output.write(value)
value = input.read
}
output.flush()
}
}
}

Of course if I comment back in the method genericResourceTrait
everything compiles. Also if I use the following implementation for
jioCloseableResourceTrait it compiles:

implicit def jioCloseableResourceTrait[A <: java.io.Closeable] = new
Resource[A] {
override def close(a: A) = a.close()
}

I struggle to see the difference between using an implicit object for
Resource[java.sql.Connection] (sqlConnectionResource) which works fine
in other parts of the code, and Resource[java.io.Closeable]
(jioCloseableResourceTrait). Does anyone know why the compiler treats
these differently? Or is there something else going on here that I
cannot spot?

Cheers,
Alf

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland