I could come up with encodings (removed the type parameters for simplification):
scala> :paste
// Entering paste mode (ctrl-D to finish)
def test0(a: A)(t : a.T) = a.test(t)
abstract class B{
val a: A
val t: a.T
def test = a.test(t)
}
// Exiting paste mode, now interpreting.
test0: (a: A)(t: a.T)Unit
defined class B
This on the other hand didn't work with case classes arguments (nor classes' for that matter).
One of the reasons your encoding wouldn't work:
scala> def test1(a: A)(t : A#T) = a.test(t)
<console>:12: error: type mismatch;
found : t.type (with underlying type A#T)
required: a.T
def test1(a: A)(t : A#T) = a.test(t)
The important part is required: a.T
(versus A#T
). The test method in A
doesn't take any T, it takes T this.T
, or in other words, the T belonging to one particular instance of A.