... o el equivalente de java.util.Function.andThen()
en Java
Function<String, String> add1 = string -> string + "1"; Function<String, String> add2 = string -> string + "2"; Function<String, Strint> add12 = add1.andThen(add2); add12.apply("") devuelve "12"
¿Cómo lo escribiría en Kotlin?
val add1 = { string:String -> string + "1" } val add2 = { string:String -> string + "2" } val add12 = ?La característica que está buscando se llama composición de funciones . Por lo que sé, no viene integrado en Kotlin (me encantaría que me corrigieran al respecto). Pero es muy fácil de escribir como una función de extensión.
infix fun<A, B, C> ((B) -> C).compose(that: (A) -> B): (A) -> C = { this(that(it)) }Ahora podemos escribir
val add1 = { string:String -> string + "1" } val add2 = { string:String -> string + "2" } println((add2 compose add1)("3")) // Prints "312" Escribo compose para usar una composición de derecha a izquierda, más acorde con la forma en que funcionan las funciones matemáticas.
De acuerdo, esto no es exactamente lo que está buscando, porque no puede almacenar una función compuesta de esta manera en una variable, pero puede encadenar los resultados de las funciones usando run si las funciones mismas no tienen el parámetro como un receptor:
fun print(string: String) { println(add1(string).run(add2)) } // or fun print(string: String) { println(string.run(add1).run(add2)) } Dado que run es una función en línea, no agrega un objeto contenedor alrededor de cada función.
La función let tendrá exactamente el mismo efecto. Esto se debe a que cuando pasa algo que no sea lambda a una función de orden superior, no importa si el primer parámetro es un receptor o no. Se tratan como la misma firma.
Si está tan familiarizado con las funciones de Java y/o quiere usarlas, todavía está abierto a hacerlo (usando java.util.function.Function ):
val add1 : Function<String, String> = Function { "${it}1"} val add2 : Function<String, String> = Function { "${it}2"} val add12: Function<String, String> = add1.andThen(add2) Si quisiera tener algo similar en Kotlin, probablemente elegiría lo que también mostró Tenfour04, es decir, use let o run :
val add1 : (String) -> String = { "${it}1"} val add2 : (String) -> String = { "${it}2"} val add12 : (String) -> String = { it.let(add1).let(add2) } // or: { add1(it).let(add2) }Si compara los dos, solo ahorra algo, si omite el tipo, pero aún está lo suficientemente claro lo que se compone.
Por supuesto, puede implementar sus propias funciones de compose o andThen . Sin embargo, si no le importa usar una biblioteca adicional, es posible que le interese Arrow , donde ya se admiten muchos casos de uso funcionales.