y
04/23/2024, 9:04 PMfun <T> identity(t: T): T = t
fun <T, E> Iterable<T>.allSameValue(f : (T) -> E = ::identity) : E? { /* ... */ }
I'm getting Required: T, Found E for the default value on the parameter. why? what's wrong with E = T?Gleb Minaev
04/23/2024, 9:08 PMT = E, everything is OK. But compiler says, "What if E != T? Then ::identity function does not fit the type (T) -> E."Gleb Minaev
04/23/2024, 9:10 PMfun main() {
listOf(1, 2, 3).allSameValue<Int, String>()
}y
04/23/2024, 9:10 PMPaul Griffith
04/23/2024, 9:10 PMidentity you have to make an explicit unsafe casty
04/23/2024, 9:11 PME and then ::identity doesn't agree with the requirement of returning ESzymon Jeziorski
04/24/2024, 6:48 AMT must be a subtype of E :
fun <T : E, E> Iterable<T>.allSameValue(f: (T) -> E = ::identity): E?
With such signature identity function would always fit into generics bound, and mapping function could be used with its result matching supertypes of T.
Example:
val l = listOf(123)
val x: Number? = l.allSameValue { it.toDouble() }y
04/24/2024, 1:21 PMfun <T> Iterable<T>.allSameValue(): T? = allSameValue { it }Szymon Jeziorski
04/24/2024, 1:50 PMT : E and not not passing any arguments would achieve basically the same, since from the default value of of f being identity function, E would just be inferred as T, since indentity takes and returns same generic type:
val l = listOf(1, 2, 3)
val x = l.allSameValue() // inferred as Int?
val z = l.allSameValue<_, Number>() // inferred as Number? because of explicit generics type declaration