I have this code:
trait Context {
implicit val e: Encoder
trait Encoder {
def write(): Unit = {
println("Test")
}
}
}
trait AsyncEncoders {
this: Context =>
class AsyncEncoder extends Encoder {
}
implicit val e = new AsyncEncoder()
}
class ConcreteContext extends Context with AsyncEncoders {
}
When I use it like this (case 1):
object Main extends App {
implicit val c = new ConcreteContext()
import c._
implicitly[Encoder].write()
}
then it compiles and prints Test
.
But when I try to call the same code inside singleton object (case 2):
object TestObject {
def apply()(implicit c: ConcreteContext): Unit = {
import c._
implicitly[Encoder].write()
}
}
object Main extends App {
implicit val c = new ConcreteContext()
TestObject()
}
compilation fails with:
path/to/Main.scala:29: could not find implicit value for parameter e: c.Encoder implicitly[c.Encoder].write()
If I change (case 3):
implicit val e = new AsyncEncoder()
to
implicit val e: Encoder = new AsyncEncoder()
then it compiles and runs as expected.
But for some reason this is not acceptable for me.
Why does compilation fail in the above case?
Encoder
as a typeclass instead of a path-dependent type. – YawarEncoder
trait is SAM and they've changed treatment of SAMs in 2.12. Not sure if this is the root cause why it compiles in 2.12 and errors in 2.11, but this is my first intuition. – Piotr Krzemiński