fun sigma(range: IntRange, f: (Int) -> Int): Int { var result = 0 for (i in range) result += f(i) return result }and we have
println(sigma(1..5) { x -> x }) // prints: 15 println(sigma(1..5) { x -> x * x }) // prints: 55We would like to to fix f() so that we could define:
val sigmaOfSum = sigma { x -> x } val sigmaOfProduct = sigma { x -> x * x }without committing to a range, such that later on, we can invoke
println(sigmaOfSum(1..5)) // prints: 15 println(sigmaOfProduct(1..5)) // prints: 55This can be done in straight Kotlin:
fun sigma(f: (Int) -> Int): (IntRange) -> Int { fun applyF(range: IntRange): Int { var result = 0 for (i in range) result += f(i) return result } return ::applyF }Here, the (higher order) function sigma takes f() as a parameter and returns a function that applies f() on the provided range.
A more down to earth example; suppose we want to perform a DB lookup. In principal, we need specify a key/query and the th DB instance but we want to break these two things apart in the spirit of the first example:
fun lookUp(db: Mapnow the following works:): (String) -> String? { fun dbLookup(key: String): String? { return db.get(key) } return ::dbLookup }
val customerLookup = lookUp(mapOf("1" to "Customer1", "2" to "Customer2")) val productLookup = lookUp(mapOf("1" to "Product1", "2" to "Product2")) println(customerLookup("1")) // prints Customer1 println(productLookup("1")) // prints Product1Our lookUp() function is quite simple and can be collapsed to:
fun lookUp(map: Map): (String) -> String? = { map.get(it) }