Aux-pattern usage compiles without inferring an appropriate type

It seems there is no deep reason for that.

Since when you specify type parameter explicitly both methods compile

def testBaz(baz: Baz) = Bar[baz.foo.T](baz.foo) //compiles
def testFoo(foo: Foo) = Bar[foo.T](foo)         //compiles

it seems in

def testBaz(baz: Baz) = Bar(baz.foo) //compiles
//def testFoo(foo: Foo) = Bar(foo)   //doesn't compile

in the first case the type baz.foo.T is inferred while in the second case the type foo.T is just not inferred

// found   : Foo
// required: Foo.Aux[this.T]

In Scala it’s always possible that some type parameter will not be inferred and you’ll have to specify it explicitly.


Maybe I found a possible reason.

The code

class testFoo2(foo: Foo) {
  // Bar(foo) // doesn't compile
}

doesn’t compile but if you make foo a val

class testFoo2(val foo: Foo) {
  Bar(foo) // compiles
}

then it does. Probably the thing is that when foo is a val it’s more “stable” and in such case it’s “easier” to infer path-dependent type foo.T.

So the difference between testBaz and testFoo can be that Baz is a case class so foo is a val while in testFoo foo is just a method parameter and therefore less “stable”.

Similarly , on contrary to

trait A[T]
def m[T](a: A[T]) = ???
m(??? : A[_]) // compiles

the code

trait A { type T } 
def m[_T](a: A { type T = _T}) = ??? 
m(??? : A) // doesn't compile

doesn’t compile but if we extract a variable

val a: A = ???
m(a) // compiles

then it does. The thing is that now a is stable and type a.T can be inferred.

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top