0

This is an extension function:

fun <T, R> Collection<T>.fold(initial: R,  combine: (acc: R, nextElement: T) -> R): R {
    var accumulator: R = initial
    for (element: T in this) {
        accumulator = combine(accumulator, element)
    }
    return accumulator
}

Is it possible to replace the second parameter which is a function with a separate function. For example, something that would look similar to this:

fun <T, R> Collection<T>.fold(initial: R, someFun)

fun someFun (acc: R, nextElement: T) -> R): R {
        var accumulator: R = initial
        for (element: T in this) {
            accumulator = combine(accumulator, element)
        }
        return accumulator
}
Sergio
  • 27,326
  • 8
  • 128
  • 149
Johann
  • 27,536
  • 39
  • 165
  • 279

2 Answers2

2

You can use two colons to pass reference to the function:

var collection = listOf<String>()
collection.fold(3, ::someFun)

fun <T, R> someFun(acc: R, nextElement: T): R {
    var accumulator: R = acc
    // ...
    return accumulator
}
Sergio
  • 27,326
  • 8
  • 128
  • 149
  • Can you show me how to do it with the code I listed because I can't seem to get it correctly. – Johann Dec 20 '18 at 15:12
  • The extension function in the first code block does compile. I took this straight from the Kotlin documentation. I want to know how to use your solution for that code. – Johann Dec 20 '18 at 15:24
0

I'm not sure why do you need to extract a function this way. The desired code in question does not compile and to propose a working alternative it's required to know your actual intent.

For example if you don't want to spell a long function signature in the type of a parameter, perhaps because you have a lot of such functions taking that type of function parameter and you afraid of making a mistake in that signature, you can extract the functional type declaration into a type alias:

typealias Combiner<R, T> = (acc: R, nextElement: T) -> R

and then use that type alias in the function declaration:

fun <T, R> Collection<T>.fold(initial: R, combine: Combiner<R, T>): R {
    var accumulator: R = initial
    for (element: T in this) {
        accumulator = combine(accumulator, element)
    }
    return accumulator
}
Ilya
  • 21,871
  • 8
  • 73
  • 92