Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

implementing methods of traits with additional implicit parameters

I want an object to implement the trait Iterable and pass an additional implicit parameter to the implemented method:

object MyRepository extends Iterable[Something] {

  def iterator(implict entityManager: EntityManager): Iterator[Something] = ...

}

Obviously this doesn't work because the iterator method has no implicit parameter and is hence not implemented by the method shown above.

An example use case is the map method which I want to apply to the repository values:

   def get = Action {
     Transaction { implicit EntityManager => 
       val result = MyRepository.map(s => s ...)
     }
   }

Is there some way to implement the Iterable trait and capture the implicit pramameter?

like image 235
deamon Avatar asked Mar 07 '13 10:03

deamon


1 Answers

Given that Iterable.iterator does not have this implicit in its signature, you cannot expect to be able to implement this method while adding this implicit: that would be another method (specifically, another overload).

However, if MyRepositorywas a class rather than an object, you could capture the implicit in the class constructor. And if you want to keep the same use style (as in MyRepository.map{ ... } rather than new MyRepository.map{ ... }), what you can do is to provide an implicit conversion from the object to the class.

Here is an example:

object MyRepository {  
  class MyRepositoryIterable(implicit entityManager: EntityManager) extends Iterable[Something] {
    def iterator: Iterator[Something] = ???
  }
  implicit def toIterable(rep: MyRepository.type)(implicit entityManager: EntityManager): MyRepositoryIterable = new MyRepositoryIterable
}

What happens now when you do MyRepository.map(...) is that the object gets implicitly converted into an instance of MyRepositoryIterable which captures the implicit EntityManager value. The MyRepositoryIterable is the class that actually implements Iterable.

like image 120
Régis Jean-Gilles Avatar answered Oct 08 '22 22:10

Régis Jean-Gilles