Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ## Background
- While Kotlin is not a pure functional language, it provides Higher order functions and an expressive way of writing programs vs statements provided by imperative languages like Java.
- ## Functions
- Function declaration
- ```kotlin
- fun <A> asString(v:A): String = v.toString
- val times2: (Int) -> Int = { n -> n * 2 }
- val sum: (Int, Int) -> Int = { x, y -> x + y }
- ```
- A function can be expressed either as `<I> functionName(arg: I): O` prefixed by the word `func` or as a `val` defined with a type defining a function from I to O `(I) -> O`
- Multiple input values can be declared as `(A, B) -> C`.
- ```kotlin
- fun intToString(n:Int) = asString(n)
- val times3 = { n:Int -> n * 3 }
- ```
- Functions can infer the return type
- Function usage
- ```kotlin
- val s = asString(8) // s = 8
- val n = times2(2)// n = 4
- val m = sum(1,2) // m = 3
- ```
- ## Higher Order Functions (map, filter, etc.)
- ```kotlin
- val xs = listOf(1,2,3,4,5)
- val ys = xs.map{ x -> x * 2 }.filter{ it < 5 }.map{ intToString(it) }
- ```
- In Kotlin, you cam use both `a -> b op c` notation or you can just refer to the element as `it`, similar to `this` within a context of a class
- ## Extension Methods
- ```kotlin
- fun Int.pow(exp:Int):Double = Math.pow(this.toDouble(), exp.toDouble())
- val r = 2.pow(3) // r = 8.0
- ```
- Simple extension method `pow(exp: Int)` for `Int`.
- ```kotlin
- fun Int.square():Double = this.pow(2)
- val r = 2.square() // r = 4.0
- ```
- Extension method `square()` uses `pow(exp: Int)` under the hood.
- ## Data Classes
- Algebraic data types (ADT)
- ```kotlin
- abstract class Tree<T>
- data class Branch<T>(val left: Tree<T>, val value: T, val right: Tree<T>): Tree<T>()
- data class Leaf<T>(val value: T): Tree<T>()
- ```
- ## Pattern matching
- ```kotlin
- fun <T,R> Tree<T>.map(f: (T) -> R): Tree<R> {
- return when(this) {
- is Branch -> Branch(this.left.map(f),f(this.value), this.right.map(f))
- is Leaf -> Leaf(f(this.value))
- else -> throw Exception("KABOOM!!!")
- }
- }
- Leaf(2).map{ it * it } // Leaf(value=4)
- ```
- `<T,R> Tree<T>.map(f: (T) -> R)` uses pattern matching to decide what to do.
- * If `this` is an instance of `Branch`, it will apply map to both sides of the tree and it will apply the function `f` to the value present in that node.
- * If `this` is a `Leaf`, it will apply the function `f` to `value`.
- * Unfortunately, Kotlin is not smart enough to tell that we have implemented all the possible scenarios, so we need to add the `else` part of the Pattern Matching throwing an exception that, we know, will never happen.
- Appart from being an example for *Pattern Matching*, `<T,R> Tree<T>.map(f: (T) -> R)` is an extension method for our ADT `Tree<T>` and it is also using [recursion][1] to apply the function `f` through the tree structure.
- Finally `<T,R> Tree<T>.map(f: (T) -> R)` is a *Higher Order Function* since it receives a function `f: (T)-> R` as its argument.
Add Comment
Please, Sign In to add comment