def foo[A](any: A): Int = 1
extension (s: String) def foo: Int = 2
val s = ""
foo(s) // 2
s.foo // 2
I would like foo(s)
to be 1. Why pick the extension when I’m invoking foo
as a function? Is there a way to avoid that?
def foo[A](any: A): Int = 1
extension (s: String) def foo: Int = 2
val s = ""
foo(s) // 2
s.foo // 2
I would like foo(s)
to be 1. Why pick the extension when I’m invoking foo
as a function? Is there a way to avoid that?
I’d guess that the extension manifests both, a vanilla method def foo(s: String): Int
in the module where the extension is declared, and the extension “sugar syntax”. The first may not fully shadow the initial def, but it would be picked as the more specific version when called with a String
argument. At least that’s how I would interpret the “Translation” section in the reference…?
It’s a feature of extension methods that they can also be called as normal functions, so not much that you can do about that. In your case you just have 2 overloaded methods foo
, one of which can also be invoked as an extension method. However you may be able to reorganize the code a bit to work around that:
def foo[A](any: A): Int = 1
class Extensions:
extension (s: String) def foo: Int = 2
given Extensions()
val s = ""
foo(s) // 1
s.foo // 2
I was hoping that the compiler would keep track of the fact that a function was defined as an extension and use that to resolve ambiguities, but it seems that it’s more of an early syntactic sugar, quickly forgotten.
Your trick works like a charm, though. It disables the use of the extension as a function, which is exactly what I want here.