2

I'm looking for a function similar to fold, which doesn't return only the final result but all intermediate results as well.

For example with fold I could implement the following example:

val res = listOf(1,2,3).fold(0, { acc, it -> f(acc, it) })
// res = 6

But I'm looking for something like...

val res = listOf(1,2,3).foo(0, { acc, it -> f(acc, it) })
// res = listOf(1,3,6)

...which then would return the intermediate results instead of just the final sum.

Is there something like this foo function already included in Kotlins stdlib or what would be a common name for this foo in functional programming style?

David Soroko
  • 8,521
  • 2
  • 39
  • 51
miho
  • 11,765
  • 7
  • 42
  • 85

3 Answers3

2

You're looking for functional operator called scan.

As of Kotlin 1.4, scan is present in the standard library.

cubuspl42
  • 7,833
  • 4
  • 41
  • 65
1

Not sure if this exists in kotlin, but that's called scan. You could see this answer for more details (not kotlin, but, since Scala influenced it a lot, probably you even wont see syntax differences).

dveim
  • 3,381
  • 2
  • 21
  • 31
  • Thank you, `scan` is exactly what I'm looking for. But you're right, kotlin seems to lag that (or at least not under that name). But at least I now know what I'm looking. – miho May 28 '18 at 10:13
  • 1
    If it lacks it, then implement it. It's not Kotlin the language that lacks it after all, just the standard library. – Marko Topolnik May 28 '18 at 10:17
  • @MarkoTopolnik: True to that! But luckily that's very easy to do in Kotlin anyways. For reference reasons: There is already exists an open issue for `scan`: https://youtrack.jetbrains.com/issue/KT-7657 (including a sample implementation). – miho May 28 '18 at 10:19
0

This can be done with the basic fold():

listOf(1, 2, 3).fold(listOf(0)) { acc, t -> acc + f(acc.last(), t) }

Complete example:

val f = { i: Int, j: Int -> i + j }
listOf(1, 2, 3).fold(listOf(0)) { acc, t -> acc + f(acc.last(), t) }
        .also { println(it) }

Prints: [0, 1, 3, 6]

David Soroko
  • 8,521
  • 2
  • 39
  • 51