2

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]();
  }


}
tharindu_DG
  • 8,900
  • 6
  • 52
  • 64
Jay
  • 1,035
  • 2
  • 11
  • 22

1 Answers1

3

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] = ...
tharindu_DG
  • 8,900
  • 6
  • 52
  • 64
Till Rohrmann
  • 13,148
  • 1
  • 25
  • 51