Probably I am missing something fundamental here, but I was refactoring certain things in my code and on the halfway I noticed that my code compiles, where I would expect it would not. So here is the method signature:
def checkUiFieldValue[T](fieldName:String, uiValue:T, expectedValue:T):Unit ={...}
Here is a place where it is used:
checkUiFieldValue("State", stateInListView(ar.name), ar.state)
The return type of the stateInListView is ARState class, while the type of the ar.state is String.
So question is why does it compile and does not tell me that types do not match? I caught myself with a thought that I expect that compiler would check that uiValue and expectedValue are of the same type T but probably my assumption is incorrect.
Or type parameter T in the method definition actually means that both arguments will be casted to Any in my case? If so then how should I properly restrict both args to have the same type at compile time?
One possible approach is to infer the types of the two arguments separately then use =:= to prove they're the same:
def test2[S, T](a: String, b: S, c: T)(implicit ev: S =:= T): T = ???
val x = test2("", new A, new A) // compiles
val y = test2("", new A, new B) // doesn't compile; can't prove A =:= B
This might be a bit strict for you though in the presence of subtyping:
class C extends B
val z = test2("", new B, new C) // doesn't compile; can't prove B =:= C
val w = test2[B, B]("", new B, new C) // does compile
As you mention, the reason why that compiles is that T is the first common type between stateInListView(ar.name) and ar.state.
You can verify this by executing these lines:
class A()
class B()
def test[T](a : String, b : T, c : T) : T = ???
val x : Any = test("ciao", new A(), new B()) // Compiles OK
val y : A = test[A]("ciao", new A(), new B()) // Does not compile: B does not work
val z : B = test[B]("ciao", new A(), new B()) // Does not compile: A does not work
Besides specifying T manually (e.g. test[A](...)), I can't really think of a way to avoid this behaviour....
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With