Search code examples
functional-programmingkotlin

Kotlin's reduce() function with different types


I was looking through array extension functions and found reduce() one

inline fun <S, T: S> Array<out T>.reduce(operation: (acc: S, T) -> S): S {
    if (isEmpty())
        throw UnsupportedOperationException("Empty array can't be reduced.")
    var accumulator: S = this[0]
    for (index in 1..lastIndex) {
        accumulator = operation(accumulator, this[index])
    }
    return accumulator
}

here the accumulator variable of type S assigned with first element from the array with type T.

Can't wrap my head around the real use case of reduce() function with two data types. Here synthetic example which actually doesn't make any sense.

open class A(var width: Int = 0)
class B(width: Int) : A(width)

val array = arrayOf(A(7), A(4), A(1), A(4), A(3))
val res = array.reduce { acc, s -> B(acc.width + s.width) }

Seems most real life use cases with this function use this signature:

inline fun <T> Array<out T>.reduce(operation: (acc: T, T) -> T): T

Can you help with providing some examples, where reduce() function can be useful with different types.


Solution

  • Here is an example:

    interface Expr {
        val value: Int
    }
    
    class Single(override val value: Int): Expr
    
    class Sum(val a: Expr, val b: Expr): Expr {
        override val value: Int
            get() = a.value + b.value
    }
    
    fun main(args: Array<String>) {
        val arr = arrayOf(Single(1), Single(2), Single(3));
        val result = arr.reduce<Expr, Single> { a, b -> Sum(a, b) }
        println(result.value)
    }