- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
could not find implicit value for evidence parameter of type ...
Mon, 2010-08-02, 14:12
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