As an example consider summing over a range of integers applying a provided function on each. Something like
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: 55
We 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: 55
This 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: Map): (String) -> String? {
fun dbLookup(key: String): String? {
return db.get(key)
}
return ::dbLookup
}
now the following works:
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 Product1
Our lookUp() function is quite simple and can be collapsed to:
fun lookUp(map: Map): (String) -> String? = { map.get(it) }
No comments:
Post a Comment