Minimal example:
fun <T> Iterable<T>.find2(elem: T) = this.find { it == elem }
Here, T
is used to both denote the type of the Iterable
, as well as the type of elem
. It seems fine, however, a statement like this is syntactically correct, but doesn't make semantic sense:
listOf(1, 2, 3).find2("foo")
I assume this works because T
resolves to Any
.
I'm aware of the solution to explicitly state the type of the function:
listOf(1, 2, 3).find2<Int>("foo")
In this case, the compiler reports an incompatibility error, and rightfully so. However, this doesn't seem to be the solution, since it requires to explicitly declare the type, and will not report an error if forgotten (which makes bugs likely).
Is there a way to "constrict" the type <T>
, so that, if, for example, the receiver is of type Iterable<Int>
, the parameter must also be Int
? In other words, is there a way to prevent the implicit cast to Any
?