Kotlin compiler throws exception while analysing my use of List.sumOf

Viewed 87

I've recently switched to Kotlin 1.5.0 which deprecated sumBy, and in the conversion process I've encountered a strange Exception while analyzing expression error from the compiler.

Here's a minimal code that produces the error, which you can run here:

fun <T> percentify(list: List<T>, fn: (T) -> Boolean): Float {
    val okCount = list.sumOf { if (fn(it)) 1 else 0 }
    if (list.isEmpty()) return 0f else return okCount/list.size
}

fun main() {
    val list = listOf(1, 2, 3)
    println(percentify(list) { it % 2 == 1})
}

My question is, am I using sumOf wrong, or is it an issue with the compiler?

1 Answers

This is definetely a bug of the compiler.

If you expicitly specify type of lambda argument(val okCount = list.sumOf { it: T -> if (fn(it)) 1 else 0 }), then it will give you another error (Overload resolution ambiguity.; this is a known bug, KT-46360)

Funny enough, but it able to overcome "resolution ambiguity" in this case if you extract lambda into separate variable (so, you may use it as a workaround):

val lambda = { it: T -> if (fn(it)) 1 else 0 }
val okCount = list.sumOf(lambda)

Or, alternatively, you may explicitly cast result of your lambda expression to Int:

val okCount = list.sumOf { (if (fn(it)) 1 else 0).toInt() }

Also, you need to manually convert okCount to Float, because (intentionally) there is no sumOf overload with Float return type:

return if (list.isEmpty()) 0f else okCount.toFloat() / list.size
Related