Is there a way to circumvent overload resolution a...
# getting-started
a
Is there a way to circumvent overload resolution ambiguity on the following two functions without giving the functions different names,
Copy code
class Zipped<out T>(val value:T)

// function one
fun <T,R> Zipped<T>.map(mapper: (T)->R): Zipped<R> {
  // . . .
}

// function two
fun <T,R> Zipped<Zipped<T>>.map(mapper: (T)->R) : Zipped<R> {
  // . . .
}

fun main() {
  val zipped: Zipped<Zipped<Int>> = Zipped(Zipped(2))
  val result = zipped.map { "zipped value: $it" } // when calling this function?
}
v
Is "one" even valid? it gives two type args.
But I guess you meant
Zipped<T>
.
e
they have conflicting JVM signatures so you need some way to keep them separate, such as putting them in separate files or using
@JvmName
to rename them
Copy code
@JvmName("zippedMap") fun <T, R> Zipped<T>.map(mapper: (T) -> R): Zipped<R> = ...
@JvmName("zipped2Map") fun <T, R> Zipped<Zipped<T>>.map(mapper: (T) -> R): Zipped<R> = ...
a
@Vampire yes, I meant Zipped<T>
@ephemient let me try it out
e
that being said, I don't think this is very good API design to have the shape of the result depend on the type of the input like this
a
Either way, it still doesn't work. it fails with override resolution ambiguity when chainning
Copy code
Zipped(0).map {
  it + 1
}.map {
  Zipped(it)
}.map { // override resolution ambiguity happens here
  it + 1
}
y
I think giving function one an extra `unit: Unit = Unit`dummy parameter could do the trick
e
being explicit on the last one
Copy code
.map { it: Int -> it + 1 }
would make override resolution unambiguous
g
It's not a solution for now, but I think marking the first declaration with
kotlin.internal.LowPriorityInOverloadResolution
should solve the problem. Currently, (if I am not mistaken) it is considered to make the declaration public (KT-32618). Also I had a bit similar issue (KT-51899) with such ambiguity.