I have this method that compares sorted lists and tells you which items from list 1 are missing from list 2, and vice versa, in O(N) time:
fun <T : Comparable<T>> compareSortedLists(
list1: Iterable<T>,
list2: Iterable<T>,
onlyInList1: MutableCollection<T>,
onlyInList2: MutableCollection<T>) {
val it1 = PeekingIterator(list1.iterator())
val it2 = PeekingIterator(list2.iterator())
while (it1.hasNext() && it2.hasNext()) {
val comp = it1.peek().compareTo(it2.peek())
if (comp < 0) // <-- ERROR: type inference failure
onlyInList1.add(it1.next())
else if (comp > 0)
onlyInList2.add(it2.next())
else {
it1.next()
it2.next() // <---- Error: type mismatch
}
}
it1.forEachRemaining { onlyInList1.add(it) }
it2.forEachRemaining { onlyInList2.add(it) }
}
The Kotlin compiler (1.2.41) in IntelliJ IDEA 2018.1.4 gives me a compile-time error (as marked above). The error message says:
Type mismatch.
Required: Comparable<Boolean>!
Found: T!
But I didn't intend the if
to be an expression. I meant it as a statement (EDIT: I mean an expression whose value is ignored, since all if
s are actually expressions). If I convert the if
to a when
then it compiles ok:
when { // <-- Look, no error! ;-)
comp < 0 ->
onlyInList1.add(it1.next())
comp > 0 ->
onlyInList2.add(it2.next())
else -> {
it1.next()
it2.next()
}
}
Why does it think the if
is an expression? And, of all things, why does it think a Comparable<Boolean>!
is required? Where's the context that requires such a type?
This seems to be a compiler bug. I reported it here:
https://youtrack.jetbrains.net/issue/KT-24886
This is a minimal reproducer:
fun <T : Comparable<T>> test(a: Iterable<T>) {
val x = if (booleanExpr1())
booleanExpr2()
else if (booleanExpr3())
booleanExpr4()
else {
a.iterator().next()
}
}
fun booleanExpr1() = true
fun booleanExpr2() = true
fun booleanExpr3() = true
fun booleanExpr4() = true
Note that the issue isn't at all with the "if expression not being treated as a statement", but with type inference itself. The compiler should have worked out a valid upper bound of all the then-branches, but failed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With