Please refer to the source code below. All source code is defined in the same package. When I define all of the code within a single source file ShowMain.scala
, I get a compile error, however when object ShowMain
is defined in ShowMain.scala
and trait Show
and object Show
are defined in Show.scala
, there is no compile error.
My question: What is the cause for this? What language rule have I run afoul of?
Example code:
object ShowMain {
def main(args: Array[String]): Unit = {
output("hello")
}
def output[A](a: A)(implicit show: Show[A]) =
println(show.show(a))
}
trait Show[-A] {
def show(a: A): String
}
object Show {
implicit object StringShow extends Show[String] {
def show(s: String) = s"[String: $s]"
}
}
Compile error:
(ScalaIDE/Scala 2.11.2 on line containing output("hello")
)
Multiple markers at this line
- not enough arguments for method output: (implicit show: test.typeclasses.show1.Show[String])Unit. Unspecified value
parameter show.
- not enough arguments for method output: (implicit show: test.typeclasses.show1.Show[String])Unit. Unspecified value
parameter show.
- could not find implicit value for parameter show: test.typeclasses.show1.Show[String]
- could not find implicit value for parameter show: test.typeclasses.show1.Show[String]
There's a rule that implicit has to be defined earlier in the compilation unit.
So, move object Show to the top and it compiles.
Alternatively,
see the explanation about the type:
https://stackoverflow.com/a/2731285/1296806