Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to say that a type parameter must have one supertype of alternative supertypes?

Tags:

scala

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 ?

like image 406
John Threepwood Avatar asked Jun 17 '12 22:06

John Threepwood


2 Answers

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.

like image 168
Niklas B. Avatar answered Nov 15 '22 07:11

Niklas B.


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
like image 43
Daniel C. Sobral Avatar answered Nov 15 '22 08:11

Daniel C. Sobral