tommy chheng
tommy chheng

Reputation: 9228

How can I pass an object in a function as an argument in Scala?

Given two objects which extend a class:

object PageDAO
  extends SalatDAO[Page, Long](collection=Config.getMongoDB("db_development")("pages"))

object BookDAO
  extends SalatDAO[Book, Long](collection=Config.getMongoDB("db_development")("books"))

I want to write a function which has the object as a parameter:

def find[ID](salatDAO:SalatDAO[Product,ID]) = salatDAO.find(MongoDBObject()).limit(10)

Like

scala> find[Long](PageDAO)
<console>:27: error: type mismatch;
 found   : PageDAO.type (with underlying type object PageDAO)
 required: com.novus.salat.dao.SalatDAO[Product,Long]
Note: Page <: Product (and PageDAO.type <: com.novus.salat.dao.SalatDAO[Page,Long]), but class SalatDAO is invariant in type ObjectType.
You may wish to define ObjectType as +ObjectType instead. (SLS 4.5)
       find[Long](PageDAO)

Is this possible?

Upvotes: 1

Views: 275

Answers (1)

Jean-Philippe Pellet
Jean-Philippe Pellet

Reputation: 60006

Just follow the advice of the compiler. If you want SalatDAO[A, _] to be a subclass of SalatDAO[B, _] when A <: B (i.e., when A is a subclass of B), declare SalatDAO to be covariant in its first parameter:

trait SalatDAO[+A, B] // ...
               ^       <-- that plus does the trick

If you cannot change the variance annotation, you can use usage-site bounds, à la Java, as Eastsun proposed in the comments:

def find[P <: Product, I](salatDAO: SalatDAO[P,I]) = // ...

Upvotes: 3

Related Questions