I’m working on a pattern matching library (Kopama), and would like to avoid specifying the type in a certain case. I simplified the example as much as I could:
class Matcher<P>(val obj: P) {
var result: String? = null
inline infix fun <reified Q : P> ((Q) -> Boolean).then(value: String) {
if (result == null && obj is Q && this(obj)) {
result = value
}
}
}
fun <P> match(obj: P, body: Matcher<P>.() -> Unit): String? =
Matcher<P>(obj).also(body).result
fun <A, B> pair(fst: (A) -> Boolean, snd: (B) -> Boolean) = { p: Pair<A, B> ->
fst(p.first) && snd(p.second)
}
fun main() {
val p = 6 to "xyz"
val s = match(p) {
pair<Int, String>({ it % 2 == 1 }, { it.length == 4 }) then "boo"
pair<Int, String>({ it % 2 == 0 }, { it.length == 3 }) then "great"
}
println(s) // "great"
}
I would like to get rid of the <Int, String>. I couldn’t find a way to do it, and there might be no solution for this at all, but maybe I overlooked something…
That would only work for top-level calls, but it would prevent pair from being useful in “inner” positions. It’s still an interesting thought, because there could be both versions with slightly different names:
fun <A, B> Matcher<Pair<A, B>>.pair(fst: (A) -> Boolean, snd: (B) -> Boolean) = { p: Pair<A, B> ->
fst(p.first) && snd(p.second)
}
fun <A, B> pair_(fst: (A) -> Boolean, snd: (B) -> Boolean) = { p: Pair<A, B> ->
fst(p.first) && snd(p.second)
}
fun main() {
val p = 6 to (1.0 to "xyz")
val s = match(p) {
pair({ it % 2 == 1 }, pair_({ it > 2.0 }, { true })) then "boo"
pair({ it % 2 == 0 }, pair_({ it < 2.0 }, { true })) then "great"
}
println(s) // "great"
}
That would be certainly better than having to type generics over and over again (and as the library also generates similar functions for data classes, there could be potentially many generics in play).
There might be the problem of inheritance - not in case of Pair, but for other types, when the pattern is not the type of the match block, but a subtype. But then you could still use the original non-extension version with generics as a “fallback”.