I have been relearning Scala after several years of being away from it. I am now trying to make sense of implicits and implicit resolution (which was always a problem in the past for me). I ran into something that indicates that I may have a more fundamental misunderstanding than I thought - especially with scoping and imports.
Consider the following:
class A {
def test(using n: Int): String = n.toString
}
object A {
given n: Int = 2
}
object Main extends App {
println((new A()).test)
}
If I try to compile this I get the following error:
no implicit argument of type Int was found for parameter n of method test in class A
I don't understand why this is the case. If I change the print expression to the following:
println((new A()).test(using A.n))
the it works (and it took me a long time to find out that this was, in fact, an allowable syntax).
The other solution, apparently, is to do the following:
import A.given
println((new A()).test)
and this works as well.
From this answer implicits are searched in the companion object of a type (which is the case here). So, my question is, I suppose, why is it that the compiler allows me to directly reference A.n
but it cannot find that implicit value on its own? Why is an import needed? It looks very much like it is in scope and should be resolved.
Part of my confusion comes from the documentation:
import
clauses are for accessing members (classes, traits, functions, etc.) in other packages. An import clause is not required for accessing members of the same package.
(from the docs). As object A
is "part of the same package" why do I need to import it or any of its members? And, in general, when is it necessary to import members when the class or object is in scope and visible? Is this something that has changed in Scala3?
Edit
Just playing around I also tried the following:
class A {
def test(using n: Int): String = n.toString
}
object A {
given n: Int = 2
}
given n: Int = 5
object Main extends App {
import A.given
println((new A()).test)
}
I expected to get a compiler error about an ambiguous implicit resolution, but it worked and printed 2
. I don't understand why this worked. If I comment out the import it prints 5
which is, at least, consistent with what I saw above.