I want to implement a cumulative sum method for List, such a function should accept List<Int>, List<Float>, etc.
I could go as far as to say that it should accept List<anything that implements add>
But I see no way of specifying this in the official documentation.
I have tried using the type Number but it apparently does not work.
How should I go about making a generic extension function that accepts any type implementing a particular method like add?
Numbers only have the following methods:
public abstract fun toDouble(): Doublepublic abstract fun toFloat(): Floatpublic abstract fun toLong(): Longpublic abstract fun toInt(): Intpublic abstract fun toChar(): Charpublic abstract fun toShort(): Shortpublic abstract fun toByte(): ByteThere is no add, so you can't add them together
typealias Adder<T> = (T)->T
fun <T: Number> T.toAdder(): Adder<T> {
return when(this) {
is Long -> {{it -> (this as Long + it as Long) as T}}
is Int -> {{it -> (this as Int + it as Int) as T}}
is Double -> {{it -> (this as Double + it as Double) as T}}
else -> throw AssertionError()
}
}
fun <T: Number> List<T>.mySum(zero: T): T {
return map { it.toAdder() }.fold(zero) { acc, func -> func(acc) }
}
fun main(args: Array<String>) {
val total = listOf(1,2,4).mySum(0)
}
This works, but it uses a lot of casting, and should be avoided
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