score:4

Accepted answer

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

score:3

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....


Related Query

More Query from same tag