Ambiguous function call based on nullability


#1

I tried to override function map based on nullability as

public inline fun <T, R> Iterable<T?>.map(transform: (T) -> R): List<R> {
  throw RuntimeException(“doesn’t matter”)
}

This works, but doesn’t seem to be possible to call:

fun main() {
  listOf(“a”) map {it}
}

It produces the message

Error:(185, 17) Kotlin: Cannot choose among the following candidates without completing type inference:
kotlin.inline public fun <T, R> kotlin.Iterable<kotlin.String?>.map(transform: (kotlin.String) -> ???): kotlin.List<???> defined in root package
kotlin.inline public fun <T, R> kotlin.Iterable<kotlin.String>.map(transform: (kotlin.String) -> ???): kotlin.List<???> defined in kotlin

And this confuses me even more, as it sounds like “Cannot do A without B”, so my question is “What doesn’t it do B”?

Is there a workaround?


#2

Am i right, you want convert list with nullables to not nullables list?

You have mistake in map. T and R by default Nullable.

http://kotlin-demo.jetbrains.com/?publicLink=1145535898113064434942057035656


#3

B7W wrote:

Am i right, you want convert list with nullables to not nullables list?

You have mistake in map. T and R by default Nullable.


I can see, I confused things. You wrote “T and R by default Nullable.”, does it mean there’s a way to use non-nullable formal type arguments? I mean something like

fun <T> f(x: T): String = x.toString() fun <T!!> f(x: T) = if (x!=null) x.toString() : "null"

where T!! is my invented syntax matching non-nullable types. This could work as the resolution is static. OTOH I doubt it's really useful.

http://kotlin-demo.jetbrains.com/?publicLink=1145535898113064434942057035656

Yes, that's fine, thanks.

I sort of resolved my confusion and filed
http://youtrack.jetbrains.com/issue/KT-5739


#4

You can use

fun <T:Any> fn()  {}

It will allow only non-nullable types for T. In fact, not specifying any constraint is same as specifying “Any?” constraint:

fun <T> fn() {}

is the same as

fun <T:Any?> fn()  {}