8

Here is a little snippet of code:

class Foo[A] { def foo[B](param: SomeClass[B]) { // } } 

Now, inside foo, how do I:
1) verify if B is the same type as A?
2) verify if B is a subtype of A?

3 Answers 3

7

You need implicit type evidences, <:< for subtype check and =:= for same type check. See the answers for this question.

Sign up to request clarification or add additional context in comments.

2 Comments

Do I have to implement these implicits by myself in case A and B are classes defined by me?
@Sergey No, just append an extra (implicit ev: B <:< A) argument list to the method. Or (implicit ev: B =:= A) for equality.
7

As a side note, generalized type constraints aren't actually necessary:

class Foo[A] { def foo_subParam[B <: A](param: SomeClass[B]) {...} def foo_supParam[B >: A](param: SomeClass[B]) {...} def foo_eqParam[B >: A <: A](param: SomeClass[B]) {...} def foo_subMyType[Dummy >: MyType <: A] {...} def foo_supMyType[Dummy >: A <: MyType] {...} def foo_eqMyType[Dummy1 >: MyType <: A, Dummy2 >: A <: MyType] {...} } 

In fact, I prefer this way, because it both slightly improves type inference and guarantees that no extraneous runtime data is used.

2 Comments

Hi @Ptharien's Flame, I've just seen your answer, and it seems interesting. Could you please explain it a little bit? Where does MyType comes from and how do you use the foo_eqMyType method? Thank you in advance for your answer.
@FrancisToth It’s just a placeholder name. I could have used Bar or Baz just as easily. In the example, MyType is meant to be some type that’s not a type parameter, but instead comes from elsewhere. As for usage of the method, you just call it! Type inference and type checking will take care of the rest automatically.
6

1) verify if B is the same type as A?

class Foo[A] { def foo(param: SomeClass[A]) = ??? } // or class Foo[A] { def foo[B](param: SomeClass[B])(implicit ev: A =:= B) = ??? } 

2) verify if B is a subtype of A?

class Foo[A] { def foo[B <: A](param: SomeClass[B]) = ??? } // or class Foo[A] { def foo[B](param: SomeClass[B])(implicit ev: B <:< A) = ??? } 

In your case, you do not need generalized type constraints (i.e. =:=, <:<). They're required when you need to add a constraint on the type parameter that is defined elsewhere, not on the method.

e.g. To ensure A is a String:

class Foo[A] { def regularMethod = ??? def stringSpecificMethod(implicit ev: A =:= String) = ??? } 

Here you cannot enforce the type constraint without a generalized type constraint.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.