Folding Results

Folding Results

Kotlin is a fantastic language. Every day, I find a new function or method that makes programming in it a breeze. One of my go-to functions I keep reaching for recently is fold. You can think of fold like a reduce; however, reduce starts with the first value in the list, whereas fold starts with the given initial value and the first item in the list.

An example always helps. We have a list of sites for a business and want to calculate the total staff numbers plus the staff at head office. We can pass the head office staff numbers in as the initial value.

val sites = listOf(
    Site("Site A", 150),
    Site("Site B", 120),
    Site("Site C", 80),
    Site("Site D", 200)
)

val headOfficeStaff = 25
val totalStaff = sites.fold(headOfficeStaff) { 
total, site -> total + site.staffCount 
}

println(totalStaff) // 575

So, we have a good idea of how to use fold now; however, it has some other interesting use cases. When dealing with the Result value in Kotlin, fold can provide some nice syntax sugar when unwrapping the values. Let's use another example.

We want to fetch the carbon footprint for a given account and year. Internally, the function calls a database to get all footprints for an account and returns a Result. We can use fold to process this Result.

fun calculateFootprint(account: String, year: Int): Double? {
    return getYearlyFootprintsForAccount(account).fold(
        onFailure = { error ->
            println("Error fetching data: ${error.message}")
            null
        },
        onSuccess = { yearlyFootprints ->
            yearlyFootprints.find { it.year == year }?.carbon
        }
    )
}

Honestly, I love fold. Not only can you use it for formatting and aggregating data, but it provides a very clean way of processing Result values.

Did you find this article valuable?

Support Alexander Karan by becoming a sponsor. Any amount is appreciated!