¿Forma funcional de acumular dentro de una function de Unidad en Kotlin?

Intento obligarme a emplear functional programming en Kotlin, y siempre que sea posible, evitar el uso de vars mutables. Normalmente, para una testing ad hoc para una function de devolución de unidades, println() algo dentro de la function para ver si funciona correctamente. Pero para esta testing, necesito acumular una cadena y finalmente usar assertEquals(...) .

Como de costumbre, me encontré declarando una var en el scope adjunto y usando += para acumularlo. ¿Hay una forma más funcional de hacer esto pasando / encadenando una function y eliminando la variable var? Aquí hay un código simplificado pero ilustrativo:

 inline fun <T> Iterable<T>.forEachFrom(beg:Int, act:(T)->Unit) { var i=0; if (beg>=0) for (e in this) if (i++ >= beg) act(e) } fun main(args:Array<String>) { val l = listOf("zero", "one", "two", "three", "four") // print-to-screen test l.forEachFrom(2){print("$it-")}; println() // output: two-three-four- // accumulate-in-var test var s = "" l.forEachFrom(2){s += "$it-"}; println(s) // output: two-three-four- // Is there a purely functional way, without declaring a mutable var? // val s = l.forEachFrom(2){accumulator???("$it-")} // - OR - // val s = l.forEachFrom(2).accumulator???("$it-") // println(s) } 

Una forma de hacer lo mismo con solo kotlin-stdlib y conservar la semántica del código (es decir, iterar solo una vez) es convertir Iterable<T> a Sequence<T> y usar la .drop(n) :

 inline fun <T> Iterable<T>.forEachFrom(beg: Int, act: (T) -> Unit) = if (beg >= 0) asSequence().drop(beg).forEach(act) else Unit 

UPD: Después de discutir la pregunta general, se nos ocurrió otro enfoque.

Cuando tiene una function personalizada de order superior que itera sobre los elementos y solo acepta una callback, pero no devuelve nada, puede ajustar esa lógica de iteración personalizada en una Sequence<T> utilizando buildSequence { ... } y pasando yield(it) como la callback:

 val sequenceFromCustomFunction = buildSequence { l.forEachFrom(2) { yield(it) } } 

Esto le permite trabajar con esta secuencia en estilo funcional y, en particular, plegar la secuencia:

 val s = sequenceFromCustomFunction.fold("") { acc, it -> acc + it + "-" } 
  • Servicios permanentes en android oreo
  • Error al configurar el reino con kotlin
  • ExpandableListView no se muestra en mi actividad
  • Cómo poner un elemento en un map y devolver el map
  • ¿Cómo corutinas puede ser más rápido que los hilos?
  • Error de compilation de la inferencia del tipo Kotlin al usar la API de Akka java
  • No se permite declarar una tarea 'limpia' personalizada cuando se usan los complementos estándar de ciclo de vida de Gradle
  • Convirtiendo el método Java "Callable <T>" a Kotlin
  • Kotlin enlazó la incoinheritance de las references invocables
  • Kotlin: cómo henetworkingar del suscriptor de RxJava
  • La cadena cruda de Kotlin arroja un error en blanco