4

I have an extension function shown below

infix fun List<Int>.sumList(that: List<Int>) =
    this.zip(that, Int::plus)

I am now trying to make this extension function generic so that it works on list of integers as well as float and double.

listOf(1,2,3).sumList(listOf(10,20,30)) gives me [11, 22, 33]

Below is my attempt of writing the same extension function using generics

inline infix fun <reified T: Number> List<T>.sumListNew(that: List<T>): List<T> = when {
    T is Double -> this.zip(that, Double::plus)
    else -> this.zip(that, Int::plus)
}

However I am getting compiler error at T saying type parameter is not an expression. Can someone help me resolve this error and also reason for getting this error?

Nagasree
  • 173
  • 2
  • 2
  • 9
  • What is the point of making this function generic if you then have to provide separate implementations for each subtype anyway? I think it would be better to just create multiple overloads. – broot Jul 24 '22 at 06:06
  • 1
    @broot One (possibly questionable) reason is so you can have only one `sum` method, instead of `sumInts`, `sumDoubles`, and so on. Though that can also be solved by using `@JvmName("sumInts")`, `@JvmName("sumDoubles")`, etc. – Slaw Jul 24 '22 at 06:09
  • 3
    I think you have to do it like this: `when(T::class) { Double::class -> (this as List).zip(that as List, Double::plus) as List`. So a lot of boilerplate. But still, I think you should use overloads and yes, with `@JvmName`. This function is unusable from Java anyway. – broot Jul 24 '22 at 06:16

1 Answers1

2

Perhaps you may do it this way by having one sum method and just overriding the plus operator for Number:

operator fun Number.plus(a : Number) : Number{
    return when(this::class){
        Int::class -> this.toInt() + a.toInt()
        Double::class -> this.toDouble() + a.toDouble()
        else -> error("Data Type not found!")
    }
}

inline infix fun <reified T: Number> List<T>.sumListNew(that: List<T>): List<T>{
    return this.zip(that,Number::plus) as List<T>
}