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(): Double
public abstract fun toFloat(): Float
public abstract fun toLong(): Long
public abstract fun toInt(): Int
public abstract fun toChar(): Char
public abstract fun toShort(): Short
public abstract fun toByte(): Byte
There 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