You are right, there are many choices. In general, type inference on generic method uses the arguments to determine the value of the generic parameter
def myMethod[A](aList:List[A])
However, this is not the only way to use type inference of generic arguments. Notably, type parameters can be :
- explicit
- determined using the expected result type
In this case, as the generic type parameter cannot be determined from the arguments (because there are no explicit arguments), you typically assign the result of the method to a typed variable, or you use it at the end of a method with explicit return type.
You might ask yourself how A1 will be solved and this is a very interesting question. In fact A1 is not present in the input type, nor in the output type. What is it useful for?
The answer is in the following definition, coming from Predef.scala
@implicitNotFound(msg = "Cannot prove that ${From} <:< ${To}.")
sealed abstract class <:<[-From, +To] extends (From => To) with Serializable
Since the <:<
is contravariant in From
the method
def joinLeft[B1 >: B, C](implicit ev: A <:< Either[C, B1]):
Either[C, B1] = this match {
case Left(a) => a
case Right(b) => Right(b)
}
won't handle correctly subclassing on A. That's why you need an extra generic type parameter A1, which is resolved by the Scala compiler by using the A1 which gives the implicit with the highest priority.