Guest User

Untitled

a guest
Jul 16th, 2018
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.83 KB | None | 0 0
  1. ## Background
  2.  
  3.  
  4.  
  5. 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.
  6.  
  7. ## Functions
  8. Function declaration
  9.  
  10. ```kotlin
  11. fun <A> asString(v:A): String = v.toString
  12. val times2: (Int) -> Int = { n -> n * 2 }
  13. val sum: (Int, Int) -> Int = { x, y -> x + y }
  14. ```
  15.  
  16. 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`
  17.  
  18. Multiple input values can be declared as `(A, B) -> C`.
  19. ```kotlin
  20. fun intToString(n:Int) = asString(n)
  21. val times3 = { n:Int -> n * 3 }
  22. ```
  23. Functions can infer the return type
  24.  
  25. Function usage
  26. ```kotlin
  27. val s = asString(8) // s = 8
  28. val n = times2(2)// n = 4
  29. val m = sum(1,2) // m = 3
  30. ```
  31. ## Higher Order Functions (map, filter, etc.)
  32. ```kotlin
  33. val xs = listOf(1,2,3,4,5)
  34. val ys = xs.map{ x -> x * 2 }.filter{ it < 5 }.map{ intToString(it) }
  35. ```
  36. 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
  37. ## Extension Methods
  38. ```kotlin
  39. fun Int.pow(exp:Int):Double = Math.pow(this.toDouble(), exp.toDouble())
  40. val r = 2.pow(3) // r = 8.0
  41. ```
  42. Simple extension method `pow(exp: Int)` for `Int`.
  43. ```kotlin
  44. fun Int.square():Double = this.pow(2)
  45. val r = 2.square() // r = 4.0
  46. ```
  47. Extension method `square()` uses `pow(exp: Int)` under the hood.
  48. ## Data Classes
  49. Algebraic data types (ADT)
  50. ```kotlin
  51. abstract class Tree<T>
  52. data class Branch<T>(val left: Tree<T>, val value: T, val right: Tree<T>): Tree<T>()
  53. data class Leaf<T>(val value: T): Tree<T>()
  54. ```
  55. ## Pattern matching
  56. ```kotlin
  57. fun <T,R> Tree<T>.map(f: (T) -> R): Tree<R> {
  58. return when(this) {
  59. is Branch -> Branch(this.left.map(f),f(this.value), this.right.map(f))
  60. is Leaf -> Leaf(f(this.value))
  61. else -> throw Exception("KABOOM!!!")
  62. }
  63. }
  64. Leaf(2).map{ it * it } // Leaf(value=4)
  65. ```
  66. `<T,R> Tree<T>.map(f: (T) -> R)` uses pattern matching to decide what to do.
  67.  
  68. * 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.
  69. * If `this` is a `Leaf`, it will apply the function `f` to `value`.
  70. * 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.
  71.  
  72. 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.
  73.  
  74. 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