I am looking at the documentation for the Kotlin fold function and am having a bit of difficulty understanding what is going on. The example they provide is as follows:
val fruits = listOf("apple", "apricot", "banana", "blueberry", "cherry", "coconut")
// collect only even length Strings
val evenFruits = fruits.groupingBy { it.first() }
.fold(listOf<String>()) { acc, e -> if (e.length % 2 == 0) acc + e else acc }
println(evenFruits) // {a=[], b=[banana], c=[cherry]}
They say there should only be a single "operation function" as an argument.
.fold(listOf<String>()) { acc, e -> if (e.length % 2 == 0) acc + e else acc }
However, in addition to the lambda, they also have the (listOf<String>())
part. While the lack of parentheses around arguments on some function calls confuses me sometimes, I imagine this can't possibly be a function call all on its own. Does the Kotlin fold Function require typecasting or specifying lambda type? If I get rid of that code snippet it breaks. I was pretty sure that the only way to specify a type was anonymous functions with a return type and not lambdas so I'm really not too sure what is going on here. I am new to Kotlin so any explanations as to what this syntax means and how the fold function works would be appreciated.
Here is the link to the documentation: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/fold.html
In the linked documentation you can see there are 2 arguments:
inline fun <T, R> Iterable<T>.fold(
initial: R,
operation: (acc: R, T) -> R
): R
By the trailing lambda rule, the call is another way to write
.fold(listOf<String>(), { acc, e -> if (e.length % 2 == 0) acc + e else acc })
So initial
is listOf<String>()
and operation
is { acc, e -> if (e.length % 2 == 0) acc + e else acc }
. The reason String
needs to be specified in listOf<String>()
is that it helps the compiler figure out that R
is List<String>
and then it knows the types of both arguments in { acc, e -> ... }
.
If I get rid of that code snippet it breaks.
If you mean just removing (listOf<String>())
then you are left with one argument, and fold
requires two.
Does the Kotlin fold Function require typecasting or specifying lambda type?
Well, there is no typecasting or specifying lambda type in the example, so it doesn't.