That is not possible, as they have the same erasure. You can build an intersection type, in Scala 2 using with
, then linearization kicks in
scala> class C { def f = 0 }
scala> class D { def f() = 1 }
scala> def m(x: C with D) = x.f() // nilary
scala> def m(x: D with C) = x.f // nullary
For Scala 3 (C & D
vs D & C
) I’m not sure exactly what’s the spec, but it seems the order also matters (Fix #7425: Handle nullary/parameterless conflicts in infoMeet · dotty-staging/dotty@20818af · GitHub).
Yes, you have to invoke f
without ()
, or provide the argument explicitly. The compiler infers implicit arguments when an entire implicit argument list is missing (and doesn’t go into eta-expansion if no implicit can be found).
For default arguments, the opposite is true: they are only used when an argument list is present, but incomplete.
scala> def f(x: Int = 1) = x
scala> f // eta-expansion in 2.14 and Scala 3
val res0: Int => Int = Lambda$1366/113202956@6c9a3661
scala> f()
val res1: Int = 1