Maxim
Maxim

Reputation: 1254

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.

Upvotes: 8

Views: 8568

Answers (2)

Andr&#233; Mion
Andr&#233; Mion

Reputation: 883

In that case, you need to use fold, where the accumulator type might be different from the array elements:

inline fun <T, R> Array<out T>.fold(
    initial: R,
    operation: (acc: R, T) -> R
): R

Upvotes: 4

JB Nizet
JB Nizet

Reputation: 691655

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)
}

Upvotes: 3

Related Questions