I’ve been trying to figure out how to specify the ...
# announcements
n
I’ve been trying to figure out how to specify the signature of a generic function when it’s used as an argument to a higher order function. I’m looking at a function that tries to compare some arguments of unknown type.If they can be cast to numbers, it compares them as numbers.  If they are strings, it compares them as stings. It’s possible to write one of these for each compare, of course, but the casting logic is duplicated. It would be nice to factor that out using a higher order function:
Copy code
compareOp(v1: Any, v2: Any, f: (Any, Any) -> Boolean): Boolean
...
compareOp(v1, v2, {x, y -> x < y})
This isn’t quite right though. The “<” on the last line doesn’t compile. Any < Any doesn’t exist. Since I’m only trying to compare as strings or numbers, it’s possible to write this as:
Copy code
compareOp(v1: Any, v2: Any, fs: (String, String) -> Boolean, fd: (Double, Double) -> Boolean): Boolean
...
compareOp(v1, v2, {x, y -> x < y}, {x, y -> x < y})
That works, but still doesn’t feel right. {x, y -> x < y} is duplicated. I should be able to pass it in just once. Its signature is:  <T> fun comparison(x: Comparable<T>, y: T): Boolean As far as I can tell, it’s not possible to stick this type parameter in the signature of compareOp. I tried making an interface Comparison<T> with an “operator fun invoke” that has the Comparable<T> signature. That still doesn’t quite work. compareOp has to specify a single explicit value for T. Has anyone solved this sort of issue?
s
Do you need the value type to be
Any
?
can’t you just define compareOp to look something like this?
Copy code
fun <T : Comparable<T>> compareOp(first: T, second: T, comparator: (T, T) -> Boolean)