Reputation: 20653
The code below fails to compile.
The purpose of this code is to inject the implicit dependencies into UseImplicit
.
In other words, it is a dependency injection for type class instances.
trait StuffProvider[T]{
implicit val provideStuff:() => T
}
trait UseImplicit{
implicit val gimmiString: StuffProvider[String] // implicit dependency
implicit val gimmiInt: StuffProvider[Int]
def foo[T:StuffProvider]() :T = implicitly[StuffProvider[T]].provideStuff()
}
object Main{
object StringProvider extends StuffProvider[String]{
implicit val provideStuff: () => String= () => "bla"
}
object IntProvider extends StuffProvider[Int]{
implicit val provideStuff: () => Int= () => 42
}
object UI extends UseImplicit {
implicit val gimmiString=StringProvider // injection
implicit val gimmiInt=IntProvider
}
val f:Int=UI.foo[Int]() // Error:(27, 15) could not find implicit value for evidence parameter of type StuffProvider[T]
}
but this compiles just fine :
trait UseImplicit2{
implicit val gimmiString: String
def foo() :String = implicitly[String]
}
object Main2{
object UI extends UseImplicit2 {
override implicit val gimmiString:String = "s"
}
val f=UI.foo() // this compiles just fine
}
I don't see what is the difference between the two codes, they have the same structure.
Why does the second compile and the first not ?
How can I make the first compile ?
The goal is that I can inject the implicits into a realization of UseImplicits
. So that I can provide several realizations (testing, production).
Scala Fiddle is here : https://scalafiddle.io/sf/dm3OJSF/1
Upvotes: 0
Views: 231
Reputation: 4017
Importing UI
implicits (by import UI._
) into current scope, right before calling UI.foo()
, should fix your issue.
You can inject the desired UseImplicit
(e.g into a Foo
class) and use it as:
case class Foo(ui: UseImplicit) {
import ui._
val f: Int = ui.foo[Int]() //Use your injected `UseImplicit`
}
Upvotes: 2