Any hints how I could avoid a recursive type checking problem in this particular case?
inline fun <reified T : Comparable<T>> calculatePackageVerificationCode(input: List<T>) =
when (T::class) {
String::class -> {
val sha1sums = input as List<String>
val digest = sha1sums.sorted().fold(DigestUtils.getSha1Digest()) { digest, sha1sum ->
DigestUtils.updateDigest(digest, sha1sum)
}.digest()
Hex.encodeHexString(digest)
}
File::class -> {
val files = input as List<File>
val sha1sums = files.map { file ->
file.inputStream().use {
DigestUtils.sha1Hex(it)
}
}
// Type checking runs into a recursive problem here.
calculatePackageVerificationCode(sha1sums)
}
else -> throw IllegalArgumentException("Unsupported type of input list.")
}
Keep both of your current functions and rename them. Maybe add List and String to the end. Than you can create a third function with the original name, which calls the correct sub function. You can than even inline all 3 functions as they would no longer be recursive.
Thanks! That works. Just wondering, is it described somewhere what mechanism allows Kotlin to distinguish these functions when called from Kotlin although the JVM can’t? The docs on handling signature clashes do not really provide an answer to that question.
The reason Kotlin can distinguish is that unlike Java it was designed from the ground up to have generics. It therefore doesn’t need to be stupid with compatibility constraints. It knows that the types are different at compile time even though they are not at runtime. The JVM of course only resolves functions on raw types so separate names are still needed.