scalascala-implicits

String companion object in scala


Given a type which has a "converter", I would like to have automatic conversion on method call using this type's companion object. That is, given the following definition,

case class Converted(name: String)

trait Converter[A] {
  def perform: Converted
}

implicit val StringConverter = new Converter[String] {
  def perform = Converted("String")
}

make the following code to work:

implicit def toConverter(a: String.type): Converted = 
  implicitly[Converter[String]].perform // Error: `Found String.type, required AnyRef`

def f(needsConverted: Converted) = ???

f(String) // <- That's what I would like to be able to write.

But this fails and both attempts for conversion fail. Note that I cannot change f because it is provided by a third-party library and there are many of them.

  1. Can I make f(String) compile using implicits?

If not possible for Strings, what about classes which do have a companion object, can I do this generically like:

object TheClass

case class TheClass()

implicit val TheClassConverter = new Converter[TheClass] {
  def perform = Converted("TheClass")
}

implicit def toConverter[A: Converter](a: A.type): Converted =
  implicitly[Converter[A]].perform // Error: `Not found value A`

implicit def toConverter(a: TheClass.type): Converted = 
  implicitly[Converter[TheClass]].perform // This works but is not generic

f(TheClass) // This works.
  1. Can I make the first toConverter to compile ?

Solution

  • Instead of defining an implicit instance for the type MyClass you can define an implicit instance for the companion type MyClass.type.

    implicit val TheClassConverter: Converter[MyClass.type] = new Converted[MyClass.type] {
      def perform = Converted("MyClass")
    }