Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scala: override implicit parameter around a call-by-name code block

Tags:

scala

Is there a way to override an implicit parameter used by functions invoked inside a control structure block? I have some code that looks like this:

def g()(implicit y: Int) {
  // do stuff with y
}

class A {
  implicit val x: Int = 3

  def f() {
    overrideImplicit(...) { // <-- overrideImplicit() is permitted to do anything it wants make it so that g() sees a different implicit val, as long as we do not explicitly declare "implicit" here (though it could happen within the method/function)
      g() // somehow sees the new implicit as opposed to x
    }
  }
}

My understanding is that even if overrideImplicit() sets the implicit inside itself, g() is still going to see the one that was in scope at the time, which is the one declared in A. I realize that one way to get the desired behavior is to explicitly state "implicit val x2: Int = 4" inside f(), but I want to avoid that and hide the fact that implicits are used. Is there any way to do this? Thanks.

like image 579
Heinrich Schmetterling Avatar asked May 13 '11 04:05

Heinrich Schmetterling


People also ask

How do you pass an implicit parameter?

The implicit parameter in Java is the object that the method belongs to. It's passed by specifying the reference or variable of the object before the name of the method. An implicit parameter is opposite to an explicit parameter, which is passed when specifying the parameter in the parenthesis of a method call.

Why does Scala have Implicits?

The implicit system in Scala allows the compiler to adjust code using a well-defined lookup mechanism. A programmer in Scala can leave out information that the compiler will attempt to infer at compile time. The Scala compiler can infer one of two situations: A method call or constructor with a missing parameter.

What is implicit object in Scala?

In Scala, objects and values are treated mostly the same. An implicit object can be thought of as a value which is found in the process of looking up an implicit of its type.


1 Answers

This is currently being done in STMs like this:

implicit object globalCtx extends Ctx
val r = ref(0)

atomic { implicit txn =>
  r := 5 // resolves `txn` as the implicit parameter instead of globalCtx
}

so to my knowledge, there is no better way to do it. At least not yet - see this discussion on SAM (Single Abstract Method) types and possibly adding them to Scala. It's suggested at one point SAM closures could solve this problem if they were implemented so that implicits inside the SAM closure are resolved once again in the context of the target type.

like image 61
axel22 Avatar answered Sep 28 '22 01:09

axel22