... or the equivalent of java.util.Function.andThen()
In Java
Function<String, String> add1 = string -> string "1";
Function<String, String> add2 = string -> string "2";
void print(String string) {
System.out.println(add1.andThen(add2).apply(string));
}
This function prints string "12"
How would I write it in Kotlin?
val add1 = { string:String -> string "1" }
val add2 = { string:String -> string "2" }
fun print(string: String) {
println(???)
}
CodePudding user response:
The feature you're looking for is called function composition. As far as I can tell, it doesn't come built-in to Kotlin (would love to be corrected on this). But it's very easy to write as an extension function.
infix fun<A, B, C> ((B) -> C).compose(that: (A) -> B): (A) -> C =
{ this(that(it)) }
Now we can write
val add1 = { string:String -> string "1" }
val add2 = { string:String -> string "2" }
println((add2 compose add1)("3")) // Prints "312"
I write compose
to use right-to-left composition, more in line with the way mathematical functions work.
CodePudding user response:
Granted, this is not exactly what you're looking for, because you can't store a composed function this way in a variable, but you can chain the results of functions using run
if the functions themselves don't have the parameter as a receiver:
fun print(string: String) {
println(add1(string).run(add2))
}
// or
fun print(string: String) {
println(string.run(add1).run(add2))
}
Since run
is an inline function, it doesn't add a wrapper object around each function.
The let
function will have the exact same effect. This is because when you pass something other than a lambda to a higher order function, it doesn't matter if the first parameter is a receiver or not. They are treated as the same signature.