How to get Implicit parameter into an anonymous function

Go To StackoverFlow.com

4

How do I get the implicit val myConnection into scope of the execute(true) function

def execute[T](active: Boolean)(blockOfCode: => T): Either[Exception, T] = {
  implicit val myConnection = "how to get this implicit val into scope"
  Right(blockOfCode)
}



execute(true){
// myConnection is not in scope
  useMyConnection()   // <- needs implicit value
}
2012-04-04 13:00
by Peter Lerche


5

You can't do this directly. Is the value of myConnection really not determined before you call execute? In this case, you could do this:

def execute[T](active: Boolean)(blockOfCode: String => T): Either[Exception, T] = {
  val myConnection = "how to get this implicit val into scope"
  Right(blockOfCode(myConnection))
}

execute(true) { implicit connection =>
  useMyConnection() 
}

Basically, you pass a parameter to the evaluated function, but then you have to remember to mark it implicit at the call site.

If you have several such implicits, you may want to put them in a dedicated, “implicit provider” class. E.g.:

class PassedImplicits(implicit val myConnection: String)

def execute[T](active: Boolean)(blockOfCode: PassedImplicits => T): Either[Exception, T] = {
  val myConnection = "how to get this implicit val into scope"
  Right(blockOfCode(new PassedImplicits()(myConnection)))
}

execute(true) { impl =>
  import impl._
  useMyConnection() 
}

If you want to avoid the import, you can provide “implicit getters” for each of your fields in PassedImplicits and write something like this, then:

implicit def getMyConnection(implicit impl: PassedImplicits) = impl.myConnection

execute(true) { implicit impl =>
  useMyConnection() 
}
2012-04-04 13:30
by Jean-Philippe Pellet
Jean, its looks very good except that my return value Either[Exception,T] is now expected to be Either[Exception,(Connection)=>T]. Is there any way to keep the return value Either[Exception,T] - Peter Lerche 2012-04-04 13:51
The current code will always return a Right or throw, never return Left. Maybe you want something like try Right(blockOfCode(new PassedImplicits()(myConnection))) catch { case ex: Exception => Left(ex) } instead - Jean-Philippe Pellet 2012-04-04 14:51
Jean, thank you for your help. I am with you on the try catch block. My problem is that the return datatype of the execute function should be Either[Exception,T] and not Either[Exception,(Connection)=>T]. How do I retain the correct return datatype - Peter Lerche 2012-04-05 15:01
I still don't understand where you see an Either[Exception,(Connection)=>T] - Jean-Philippe Pellet 2012-04-05 15:31
Ads