Applying implicit generic parameters to a list via

2019-09-14 04:47发布

问题:

I would like to apply a function to all objects in a list, where all objects in the list inherit from a common class. In this function, I would like to use an implicit class to ensure that the correct operation is applied based on the object's type.

For example, I want to ensure that all Employee objects in a list are converted using the employeeConverter below. Calling convert with the Employee directly works just fine, but applying convert to a list of Employee objects is a compiler error.

import scala.reflect.ClassTag

object Example {
  abstract class Person { def age: Int }

  case class Employee(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]()

    println(convert(Employee(1)))

    //println(List(Employee(2)) map convert) // COMPILER ERROR
  }
}

The above code correctly prints the following:

$ scalac Example.scala && scala Example
(Employee(1),Employee(1))

However, if I uncomment the line indicated with COMPILER ERROR, I get this compiler error:

Example.scala:20: error: could not find implicit value for parameter converter: Example.Converter[T]
    println(l map convert)
                  ^

Is this a problem that can be resolved using ClassTag? How can I modify this example to apply convert to a list?

回答1:

The compiler needs a little bit of hand-holding in this case. This works:

println(List(Employee(2)) map { e => convert(e) })