6

One can say a type parameter T must have a specific supertype S_1:

class Test[T <: S_1] 

Is there a way to say, that a type parameter must have at least one supertype of multiple supertype alternatives ? Something like (pseudocode) :

class Test[T <: S_1 || S_2] 

Or: Is this not possible, because such a construction makes no sense and would be a hint of a design mistake in the code ?

John Threepwood
  • 15,593
  • 27
  • 93
  • 149
  • Can you give an example of how that might be used? Are you thinking of a case in which objects of type parameter `T` will only use a method that happens to have the same signature in the unrelated types `S_1` and `S_2`? – Ray Toal Jun 17 '12 at 22:19
  • 4
    What you are looking for is a *union type*; see this question: http://stackoverflow.com/q/3508077/770361 – Luigi Plinge Jun 18 '12 at 00:17

2 Answers2

9

Short answer: The intuitive solution is to make S_1 and S_2 share a common trait that represents the set of abilities you require for your type parameter T. Use that trait as the upper bound for T.

More possibilities:

  • If S_1 and S_2 are unrelated in nature and your requirement for the type T is that it has certain members (that both S_1 and S_2 happen to implement), you can use a structural type to formulate that (the concept behind is called duck typing).

  • If for some reason you really require T to be a subclass of S_1 or S_2, and you can't change those types, you can use implicits to convert both of these to a newly introduced internal type S_1_or_2, which you can then use as an upper bound for your T.

Niklas B.
  • 92,950
  • 18
  • 194
  • 224
3

Let me expand on Niklas second alternative. Implicit parameters can be used to prove something about the type, so this seems like just the thing. It would go like this:

class ThingIWantToProve[T]
object ThingIWantToProve {
  // Here I define the proofs I need
  implicit def s1IsProvable: ThingIWantToProve[S_1] = new ThingIWantToProve[S_1]
  implicit def s2IsProvable: ThingIWantToProve[S_2] = new ThingIWantToProve[S_2]
}
class Test[T : ThingIWantToProve] // here I use a context bound
Community
  • 1
  • 1
Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681