2016-07-14 8 views
0

Я хотел бы применить функцию ко всем объектам в списке, где все объекты в списке наследуются от общего класса. В этой функции я хотел бы использовать класс implicit, чтобы гарантировать, что правильная операция применяется на основе типа объекта.Применение неявных общих параметров к списку через ClassTag

Например, я хочу, чтобы все Employee объектов в списке преобразуются с использованием employeeConverter. Вызов convert с Employee напрямую работает просто отлично, но применение convert к списку объектов Employee является ошибкой компилятора.

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 
    } 
} 

Приведенный выше код правильно печатает следующее:

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

Однако, если я раскомментировать строку, указываемой COMPILER ERROR, я получаю эту ошибку компилятора:

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

Является ли это проблемой что можно решить с помощью ClassTag? Как я могу изменить этот пример, чтобы применить convert к списку?

+0

Не имеет значения, если вы используете более формальный 'println (List (Employee (2)). Map (e => convert (e)))'? –

+0

Они печатаются неважно - это «Преобразование карты списка (Employee (2)», которое не удается скомпилировать. Печать только для иллюстрации результата. –

+0

Боб прав, компилятор просто не может найти неявный параметр из-за синтаксис, который вы используете. – nkconnor

ответ

2

В этом случае компилятору необходимо немного ручного удерживания. Это работает:

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