2

Hi I read the interesting post from Debasish about the implicitly function. I have wrote this code:

def find[C <: Business](id: String) = {
  collection.findOneByID(id).map(x=> implicitly[DBObject => C].apply(x))
}

but it fails to compile with this compiler message:

could not find implicit value for parameter e: (com.mongodb.casbah.commons.Imports.DBObject) => C

what is my fault? anyone can help me?

UPDATE

My idea was this: find is declared in a trait don't know nothing about DBObject, I don't want to put this dependency.

 trait BusinessRepository {
   def find[C <: Business](id: String): Option[C]
 }

class MongoBusinessRepository {

  val collection = ..

  def find[C <: Business](id: String): Option[C] = {
    collection.findOneByID(id).map(x=> implicitly[DBObject => C].apply(x))         
  }

  implicit def DBObject2Hotel(x: DBObject): Hotel = {
    // ... 
    // returning Hotel
  }
}

case class Hotel(...) extends Business(...)
Filippo De Luca
  • 704
  • 5
  • 21

2 Answers2

7

implicitly is just a convenience method to look up an implicit value that you know already exists. So it fails to compile when there is no such implicit value in scope.

A possible use case is when you use shortcut syntax for context bounds:

def find[C: Numeric](a: C, b: C): C = implicitly[Numeric[C]].plus(a, b)

Of course, in this example, the explicit form is less verbose

def find[C](a: C, b: C)(implicit n: Numeric[C]): C = n.plus(a, b)

You will find more thorough explanations in this Stackoverflow thread.


What I imagine you had in mind with your method is rather

def find[C <: Business](id: String)(implicit fun: DBObject => C) =
  collection.findOneByID(id).map(fun)
Community
  • 1
  • 1
0__
  • 66,707
  • 21
  • 171
  • 266
1

I think that the problem comes from the fact that Scala compiler try to find an implicit definition of a function DBObject => C and that the only implicit definition that he can find is DBObject => Hotel that could be a solution but it's not strict. With your solution, the compiler is not able to know what should be C.

Maybe you should consider defining a DBObject2Business and so implicitly define a DBObject => Business function, or change your design to define C in a concrete class.

David
  • 2,399
  • 20
  • 17