Writing Higher-Order Functions
When you write a function, you must declare the types of its parameters. But how do you do that when one of those parameters is itself a function?
The general syntax for specifying a function type is
( parameter-types ) -> return-type
For example, consider this predicate:
fun isEnglishVowel(c: Char) = c.lowercase() in "aeiou"
The type of this function is
(Char) -> Boolean
Now let’s write a higher-order function that has a parameter of this type.
Imagine that we need a function howMany() to count the number of
characters in a string that satisfy a given predicate. (There is actually
no need for such a function, as strings support the count() operation
already, but let’s pretend that this doesn’t exist…)
We could implement howMany() like so:
fun String.howMany(include: (Char) -> Boolean): Int {
var count = 0
for (character in this) {
if (include(character)) {
count += 1
}
}
return count
}
Notice the String. prefix to the function name on the first line. This
defines howMany() as an extension function of the String class and
allows us to invoke it as if it were a method of that class.
howMany() has a single parameter, include, with a type of
(Char) -> Boolean: i.e., a function that takes a single Char and returns
a Boolean.
The for loop iterates over the characters of the string on which
howMany() has been invoked. We refer to that string using the special
variable name this.
Task 8.5
Try using the howMany() function described above.
-
In the
tasks/task8_5subdirectory of your repository, create a file namedCount.kt, containing the definition ofhowMany()shown above. Check that the code compiles before proceeding further. -
Add a
main()function that creates a string and then callshowMany()on it in various ways, using different lambdas as the argument.