Search code examples
scalagenericsimplicittype-bounds

scala how to declare a type define which must have implicit conversion?


I need call a function def fromJsonString[Result <: B : C](jsonString: String): Result = ???.

And I define a trait MyContext in order to matching a various instance of type Result.

MyContext define like this:

trait MyContext {
  type Result <: B : C // cannot compile accutally 
  def getResult(jsonString): Result = fromJsonString(jsonString)
}

How can I declare the common type of type Result <: B : C? Thanks


Solution

  • Foo : Bar is not a type, nor an implicit conversion.
    Is just syntax for an implicit / using parameter.

    // This is sugar syntax for:
    def fromJsonString[A <: GeneratedMessage : GeneratedMessageCompanion](str: String): A
    
    // In Scala 2:
    def fromJsonString[A <: GeneratedMessage](str: String)(implicit ev: GeneratedMessageCompanion[A]): A
    
    // In Scala 3:
    def fromJsonString[A <: GeneratedMessage](str: String)(using GeneratedMessageCompanion[A]): A
    

    As such, the best you can do is to add that value to your interface.

    // Scala 2:
    trait MyContext {
      type Result <: GeneratedMessage
      implicit val companion: GeneratedMessageCompanion[Result]
    
      final def getResult(jsonString): Result = fromJsonString(jsonString)
    }
    
    // Scala 3:
    trait MyContext {
      type Result <: GeneratedMessage
      given GeneratedMessageCompanion[Result]
    
      final def getResult(jsonString): Result = fromJsonString(jsonString)
    }