0
votes

Imagine I had some function that takes a String explicitly and an T implicitly:

object SomeNamespace {
  def myFunction(arg: String)(implicit t: T)
}

And I had a superclass which provides the T

trait TProvider {
  val t: T = ...
}

And in a subclass I use extends TProvider and try to use the function

class Child extends TProvider {
   SomeNamespace.myFunction("somestring")
}

I would get an error "could not find implicit value for parameter t". My workaround is to reassign the superclass val to a new implicit one in the subclass like:

 implicit val subclassImplicitT = t

and that works ... but is kind of ugly. Is there some better way to "implicitify" a variable?

2
Where is myFunction defined? In Child or TProvider?adrice727
its defined elsewhere ... i can add that contexthiroprotagonist

2 Answers

0
votes

Eh... "implicitifying" something after it has already been declared is not really easy to do in Scala. Honestly either just passing it in as an explicit parameter is probably your best bet. Here's an alternative that is marginally nicer at best.

trait TProvider {
  // Yep it's gotta be a def for this to work, not a val,
  // because you can't call super.t if t is a val
  // (https://issues.scala-lang.org/browse/SI-1938)
  def t: T
}

class Child extends TProvider {
  // You can override it as a val though
  override implicit val t = super.t

  myFunction("something")
}
0
votes

FWIW, I ended up solving this problem in my own project by simply making another class where the t was implicit -- so like

trait ImplicitTProvider {
  implicit val t: T = ...
}

And then extended from that class instead of the TProvider.

This made sense for this project since I don't see either of these classes changing much. But not a great general solution perhaps.