Why do I need to indicate the type of function's generic type parameter that should be inferred

I have the following example:

``````    trait MBase {
type All
def all: All
}

case class aMBase() extends MBase {
type All = (Double, Double)
def all: All = (1,2)
}

def map[T<:MBase](l: List[T], f: T => T#All) : List[T#All] = {
l.map(f)
}
``````

To use it I do:

``````    val ll = List(aMBase(), aMBase())
def pp(b: aMBase) : b.All= b.all
val rr: List[(Double, Double)] = map[aMBase](ll, pp)
``````

However, the following fails:

``````    val rr: List[(Double, Double)] = map(ll, pp)
``````

I get the error (scalac 2.12.2):

``````no type parameters for method map: (l: List[T], f: T => T#All)List[T#All] exist so that it can be applied to arguments (List[aMBase], aMBase => (Double, Double))
[error]  --- because ---
[error] argument expression's type is not compatible with formal parameter type;
[error]  found   : aMBase => (Double, Double)
[error]  required: ?0T => ?0T#All
[error]     val rr: List[(Double, Double)] = map(ll, pp)
``````

Shouldnâ€™t the compiler know that ?0T <: MBase and therefore bind 0T to aMBase?
If not, why?

TIA

There are probably a few ways to do this, but if you introduce a type parameter for the refinement Scala will be able to infer the return type.

``````def map[T <: MBase, A](l: List[T { type All = A }], f: T => A) : List[A] = {
l.map(f)
}

...

val rr = map(ll, pp) // compiles
``````

Ok, see the issue now. Seems this is the same issue that requires the use of the Aux pattern.

Thank you.