I noticed that tuple.productIterator always returns an Iterator[Any] an wondered if it’s not possible to set multiple lower bounds (so it could be an Iterator of the lowest common super type).
I tried and searched a bit, but only found this question for multiple upper bounds.
This is my test on how to define the the type of the iterator:
def f[A,B](a:A, b:B) = List(a,b)
// return type is List[Any]
def f[A,B, T >: A "and" T >: B](a:A, b:B) = List[T](a,b)
// doesn't compile, but
// f(1, true) should give a List[AnyVal] and
// f("x", "y") a List[String]
Is this a limitation of the JVM?
Edit:
Here’s a slightly bigger example which doesn’t seem to be solvable using IttayD approach when T should be defined in the method:
class Foo[A, B](a: A, b: B) {
def f[T >: A] = List[T](a) // works
def g[T >: A "and" T >: B] = List[T](a) // doesn't work
}
For the simple case where
AandBare bound by the compiler as the same time asT, IttayD’s answer works fine:When
AandBare already bound as in yourclass Foo[A, B]example, you need to introduce temporary dummy variables to have the compiler do this job:(For the sake of clarity:
A1 >: A <: Tmeans that typeA1must be a supertype ofAand a subtype ofT, and not thatAis a subtype of bothA1andT.)A1andB1are here for the sole purpose of inferring a correct type forT. If the compiler has to infer them, they will resolve toA1 = AandB1 = B, and thenTas the most specific type which is a superclass of bothAandB.One thing that the compiler doesn’t realize, though, is that, by transitivity, we have both
T >: AandT >: B, which follows directly from the constraints with respect toA1andB1. We need to help out with the type ascriptions.Now,
Product#productIteratorcould not use this technique, as it’s defined in a place where we don’t even knowAandB, or indeed how many type parameters there are in the concrete subclass.