2
votes

Expanding on a bit further on a previous similar question I posted yesterday

Employee and Manager both extend Person. I've defined implicit "converter" objects for both subclasses.

I also created a list of type List[Product with Serializable with Person] that contains one of each concrete class.

import scala.reflect.ClassTag

object Example {
  trait Person { def age: Int }

  case class Employee(age: Int) extends Person
  case class Manager(age: Int) extends Person

  class Converter[T] { def convert(t: T) = (t,t) }

  def convert[T <: Person:ClassTag](p: T)(implicit converter: Converter[T]) =
    converter.convert(p)

  def main(args: Array[String]): Unit = {
    implicit val employeeConverter = new Converter[Employee]()
    implicit val managerConverter = new Converter[Manager]()

    convert(Employee(1)) // Works
    convert(Manager(2)) // Works

    List(Employee(3),Manager(4)) map(e => convert(e)) // Compile error
  }
}

converting an Employee and a Manager separately works fine, but when I try to convert the list, the Scala compiler complains because it can't find a Converter for a Person:

$ scalac Example.scala && scala Example
Example.scala:21: error: could not find implicit value for parameter converter: Example.Converter[Product with Serializable with Example.Person]
    List(Employee(3),Manager(4)) map(e => convert(e))

How can I guarantee to the Scala compiler that I have defined an implicit conversion for all concrete implementations of Person?

1
You surely need specific static type to select the implicit. Isn't that what HList is for.som-snytt

1 Answers

-1
votes

No, it cannot. Have a look at the Scala documentation http://scala-lang.org/files/archive/spec/2.11/07-implicits.html

However, if there are conflicts with implicits caused by the class hierarchy / inheritance the most specific one will be chosen. So if Manager inherited from Employee, it should resolve just fine.

Similar post here, What are scala's rules for resolving conflicting implicit values