I'm learning Scala by working the exercises from the book "Scala for the Impatient". One question asks:
Given a mutable
Pair[S, T]class, use a type constraint to define a swap method that can be called if the type parameters are the same.
My code:
class Pair[T, S](var first: T, var second: S) {
def swap(implicit ev: T =:= S) {
val temp = first
first = second // doesn't compile
second = temp
}
}
The code above fails to compile with the complaint that first and second are different types. Well, I just nicely told the compiler that they're not. How can I tell it to shut up?
You've just told the compiler that types passed to your class as
TandSshould be equal - you just require an evidence of their equality, which can be used to infer actualTandScorrectly when you pass actual types (but not inside generic class itself). It doesn't mean thatTandSare interchangable. Btw, it doesn't change anything but you did a mistake by defining newSandT, should be:However it's still doesn't compile. Why? Just think of it:
So what is return type compiler should infer?
List[T]orList[S]. the only it can do isList[Any]. So having same and different types simulteniously has no sense. If you want different names - just usetype S = Tno evidence will be needed.And what is the real case of having
SandTdifferent in constructor and same in some method. It's simply logically incorrect (when talking about abstract types - not concrete substitutions).Btw,
=:=is not the compiler feature - there is no special processing for that in compiler. The whole implementation is it inside scalaPredef:So it's just
tpEquals[A]implicit which takes typeAand gives youA =:= A- when you requireT =:= Uit's trying to make such conversion which is possible only for equal types. And the process of checking implicit itself actually happens only when you pass actualTandU, not when you defining them.About your particular problem:
Or just (as @m-z and @Imm suggested):
T =:= SextendsT => Sand this implicitly added function (even as an object) is interpreted as implicit conversion fromTtoSin Scala, so it works like both types are equal, which is pretty cool.