Kotlin supports Higher order functions. In this blog, I will create a higher order function that will use map & fold right for execution.

Before diving into higher order functions, let’s go through map & fold right.

map is collective transform operation.

var numbers = mutableListOf(1, 2, 3)
numbers = numbers.map { it*2 }.toMutableList()
// elements in numbers: 2,4,6

foldRight accept initial state, apply initial state to all elements and return final state.

var numbers = mutableListOf(1, 2, 3)
var result = numbers.foldRight(100, {a,b -> test(a,b)})
private fun test(a: Int, b: Any): Int {
        return a + b as Int
}

/*
First execution: 
initial 100
a = 3
b = 100

Second Execution
a = 2
b = 103

Third Execution
a = 1
b = 105

final: result = 106
*/

Let’s create a higher order function Middleware that takes an instance StringApp, has inner function next: Type and return Type.

typealias Type = (value: String) -> Unit
typealias Middleware = (stringApp: StringApp) -> (next: Type) -> Type

Now, create three classes that implements Middleware.

class MiddlewareA : Middleware {
    override fun invoke(stringApp: StringApp) = { next: Type ->
        { value: String ->
            next("$value MiddlewareA ")
        }
    }

}

class MiddlewareB : Middleware {
    override fun invoke(stringApp: StringApp) = { next: Type ->
        { value: String ->
            next("$value MiddlewareB ")
        }
    }
}

class MiddlewareC : Middleware {
    override fun invoke(stringApp: StringApp) = { next: Type ->
        { value: String ->
            next("$value MiddlewareC ")
        }
    }
}

StringApp class receives list of middlewares and call dispatch to execute higher order function.

class StringApp(private val middlewares: MutableList<Middleware>) {

    private fun reduce(value: String) {
        val result = value;
        // result = 
    }

    fun dispatch(value: String) {
        var dispatch2 = middlewares[2](this)(::reduce)
        var dispatch1 = middlewares[1](this)(dispatch2)
        middlewares[0](this)(dispatch1)(value)
    }
}

The higher order function can be written as below:

val app = StringApp(mutableListOf(MiddlewareA(), MiddlewareB(), MiddlewareC()))
app.dispatch("init")

{
    middlewareC -> set string value to "init middleware A middleware B middleware C"

    {
        middlewareB -> set string value to "init middleware A middleware B"

        {
            middlewareA -> set string value to "init middleware A"
        }
    }
}

Let’s use map & fold right to execute higher order function.

class StringApp(middlewares: MutableList<Middleware>) {

    // map inject store reference to all middleware functions
    private val middlewareMap: List<(Type) -> Type> = 
        middlewares.map { m -> m.invoke(this) }

    /*
        // now below code execution required to achieve result
        var dispatch2 = middlewareMap[2](::reduce)
        var dispatch1 = middlewareMap[1](dispatch2)
        middlewareMap[0](dispatch1)(value)
    */

    var middlewareDispatch = compose(middlewareMap)(::reduce)

    // traverse through middlewares
    // build middleware chain by injecting dispatch from previous middleware
    // inject ::reduce to last middleware
    private fun compose(functions: List<(Type) -> Type>): (Type) -> Type =
        { dispatch ->
            functions.foldRight(
                dispatch,
                { nextDispatch, composed -> nextDispatch(composed) })
        }

    private fun reduce(value: String) {
        val result = value;
    }


    private fun dispatch(value: String) {
        middlewareDispatch(value)
    }
}

I learned map & fold while implementing redux middleware concepts from library kotlin-redux.

Using higher order functions for middleware helps to stop middleware chain execution. If a middleware subscribes to service, on async callback the middleware can finish the work without invoking next middleware.