Here is a little snippet of code:
class Foo[A] {
def foo[B](param: SomeClass[B]) {
//
}
}
Now, inside foo
, how do I:
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.
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.
You need implicit type evidences, <:<
for subtype check and =:=
for same type check. See the answers for this question.