Функциональный способ накопления внутри функции Единицы в Котлине?

Я пытаюсь заставить себя использовать функциональное программирование в Котлине, и, когда это возможно, избегайте использования изменчивых варов. Обычно, для специального теста для функции возврата единицы, я бы просто println() что-то внутри функции, чтобы убедиться, что она работает правильно. Но для этого теста мне нужно assertEquals(...) строку, а затем в конечном счете использовать assertEquals(...) .

Как обычно, я обнаружил, что объявляю var в охватывающей области и используя += для накопления в нем. Есть ли более функциональный способ сделать это, передав / связав функцию и исключив переменную var? Вот несколько упрощенных, но иллюстративных код:

 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) } 

Способ сделать то же самое с kotlin-stdlib и сохранить семантику кода (т. Е. Повторить только один раз) – это преобразовать Iterable<T> в Sequence<T> и использовать .drop(n) :

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

UPD: обсудив общий вопрос, мы пришли к другому подходу.

Когда у вас есть пользовательская функция более высокого порядка, которая выполняет итерацию по элементам и принимает только обратный вызов, но ничего не возвращает, вы можете обернуть эту пользовательскую логику итерации в Sequence<T> , используя buildSequence { ... } и передав yield(it) как обратный вызов:

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

Это позволяет вам работать с этой последовательностью в функциональном стиле и, в частности, сворачивать последовательность:

 val s = sequenceFromCustomFunction.fold("") { acc, it -> acc + it + "-" }