In this simple code i have a method buildResponse
which takes a type parameter T which must be a subtype of Response
.
Now the compiler tells me it does not find an implicit value when i call new ResponseBuilder().build\[T]()
inside alltough i have defined an implicit for class Response in the Builder companion object.
I thought due T must be a subtype of Response
it will take the implicit value for Builder[Response]
. If T would be something else then Response
i would have excpected this error.
So whats the right way to get this done ?
import scala.util.Try;
object Main extends App {
case class Response(val v:String){
}
sealed trait Builder[T] {
def build(): Try[T]
}
object Builder {
implicit val BuilderResponse = new Builder[Response] {
def build(): Try[Response] = {
Try {
Response("Hello")
}
}
}
implicit val BuilderInt = new Builder[Int] {
def build(): Try[Int] = {
Try {
1
}
}
}
}
class ResponseBuilder
{
def build[T:Builder]() : Try[T] = {
implicitly [Builder[T]].build()
}
}
// works fine
//new ResponseBuilder().build[Response]();
//not enough arguments for method build: (implicit evidence$1: Main.Builder[T])scala.util.Try[T]. Unspecified value parameter evidence$1.
def buildResponse[T <: Response ]() : Try[T] = {
new ResponseBuilder().build[T]();
}
}
The problem is not that you need an implicit value of type Builder[Response]
but of type Builder[T]
. The implicit value BuilderResponse: Builder[Response]
cannot be used here because T
can be any subtype of Response
.
You can make the code compiling by either adding a Builder
context bound to your method buildResponse
def buildResponse[T <: Response: Builder]() : Try[T] = {
new ResponseBuilder().build[T]();
}
Or by defining an implicit method createBuilder[T <: Response]: Builder[T]
in the Builder
companion object which generates the Builder
objects somehow.
implicit def createBuilder[T <: Response]: Builder[T] = ...