-
A higher-order function is a function that takes functions as parameters, or returns a 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 }
To call fold, you need to pass an instance of the function type to it as an argument, and lambda expressions are widely used for this purpose at higher-order function call sites:
val items = listOf(1, 2, 3, 4, 5) // Lambdas are code blocks enclosed in curly braces. items.fold(0, { // When a lambda has parameters, they go first, followed by '->' acc: Int, i: Int -> print("acc = $acc, i = $i, ") val result = acc + i println("result = $result") // The last expression in a lambda is considered the return value: result }) // Parameter types in a lambda are optional if they can be inferred: val joinedToString = items.fold("Elements:", { acc, i -> acc + " " + i }) // Function references can also be used for higher-order function calls: val product = items.fold(1, Int::times)
-
Kotlin uses function types, such as
(Int) -> String
, for declarations that deal with functions:val onClick: () -> Unit = ...
. -
The full syntactic form of lambda expressions is as follows:
val sum: (Int, Int) -> Int = { x: Int, y: Int -> x + y }
If you leave all the optional annotations out, what's left looks like this:
val sum = { x: Int, y: Int -> x + y }
-
According to Kotlin convention, if the last parameter of a function is a function, then a lambda expression passed as the corresponding argument can be placed outside the parentheses:
val product = items.fold(1) { acc, e -> acc * e }
If the lambda is the only argument in that call, the parentheses can be omitted entirely:
run { println("...") }
-
it: implicit name of a single parameter
If the compiler can parse the signature without any parameters, the parameter does not need to be declared and -> can be omitted. The parameter will be implicitly declared under the name it:
ints.filter { it > 0 } // this literal is of type '(it: Int) -> Boolean'
-
You can explicitly return a value from the lambda using the qualified return syntax. Otherwise, the value of the last expression is implicitly returned.
ints.filter { val shouldFilter = it > 0 shouldFilter } ints.filter { val shouldFilter = it > 0 return@filter shouldFilter }