## Functional Programming in Kotlin by Tutorials

First Edition · Android 12 · Kotlin 1.6 · IntelliJ IDEA 2022

#### Before You Begin

Section 0: 5 chapters

#### Section II: Data Types & Typeclasses

Section 2: 5 chapters

# D. Appendix D: Chapter 4 Exercise & Challenge Solutions Written by Massimo Carli

## Exercise 4.1

Can you write a lambda expression that calculates the distance between two points given their coordinates, `x1, y1` and `x2, y2`? The formula for the distance between two points is `distance = √(x2−x1)²+(y2−y1)²`.

### Exercise 4.1 solution

You can approach this problem in different ways. Assuming you pass all the coordinates as distinct parameters, you can write the following code:

``````val distanceLambda = { x1: Double, y1: Double, x2: Double, y2: Double -> // 1
val sqr1 = (x2 - x1) * (x2 - x1) // 2
val sqr2 = (y2 - y1) * (y2 - y1) // 2
Math.sqrt(sqr1 + sqr2) // 3
}
``````
``````typealias Point = Pair<Double, Double>

val distanceLambdaWithPairs = { p1: Point, p2: Point ->
val sqr1 = Math.pow(p1.first - p2.first, 2.0)
val sqr2 = Math.pow(p1.second - p2.second, 2.0)
Math.sqrt(sqr1 + sqr2)
}
``````
``````fun main() {
println(distanceLambda(0.0, 0.0, 1.0, 1.0))
println(distanceLambdaWithPairs(0.0 to 0.0, 1.0 to 1.0))
}
``````
``````1.4142135623730951
1.4142135623730951
``````

## Exercise 4.2

What’s the type for the lambda expression you wrote in Exercise 4.1?

### Exercise 4.2 solution

The type of `distanceLambda` is:

``````val distanceLambda: (Double, Double, Double, Double) -> Double
``````
``````val distanceLambdaWithPairs: (Point, Point) -> Double
``````
``````val distanceLambdaWithPairs: (Pair<Double, Double>, Pair<Double, Double>) -> Double
``````

## Exercise 4.3

What are the types of the following lambda expressions?

``````val emptyLambda = {} // 1
val helloWorldLambda = { "Hello World!" } // 2
val helloLambda = { name: String -> "Hello \$name!" } // 3
val nothingLambda = { TODO("Do exercise 4.3!") } // 4
``````
`````` typealias AbsurdType = (Nothing) -> Nothing
``````

### Exercise 4.3 solution

You start by looking at:

``````val emptyLambda = {}
``````
``````val emptyLambda: () -> Unit
``````
``````val helloWorldLambda = { "Hello World!" }
``````
``````val helloWorldLambda: () -> String
``````
``````val helloLambda = { name: String -> "Hello \$name!" }
``````
``````val helloLambda: (String) -> String
``````
``````val nothingLambda = { TODO("Do exercise 4.3!") }
``````
``````val nothingLambda: () -> Nothing
``````

#### Nothing and lambda

Given the type:

``````typealias AbsurdType = (Nothing) -> Nothing
``````
``````val absurd: AbsurdType = { nothing -> throw Exception("This is Absurd") }
``````
``````fun main() {
absurd(TODO("Invoked?"))
}
``````
``````fun main() {
absurd(throw Exception("Invoked?"))
}
``````

## Exercise 4.4

Can you implement a function simulating the short-circuit and operator with the following signature without using `&&`? In other words, can you replicate the short-circuiting behavior of `left && right`:

``````  fun shortCircuitAnd(left: () -> Boolean, right: () -> Boolean): Boolean
``````

### Exercise 4.4 solution

In Kotlin, `if` is an expression, so you can implement `shortCircuitAnd` like this:

``````fun shortCircuitAnd(
left: () -> Boolean,
right: () -> Boolean
): Boolean = if (left()) {
right()
} else {
false
}
``````
``````fun main() {
val inputValue = 2
shortCircuitAnd(
left = { println("LeftEvaluated!"); inputValue > 3 },
right = { println("RightEvaluated!"); inputValue < 10 },
)
}
``````
``````LeftEvaluated!
``````
``````LeftEvaluated!
RightEvaluated!
``````

## Exercise 4.5

Can you implement the function `myLazy` with the following signature, which allows you to pass in a lambda expression and execute it just once?

``````fun <A: Any> myLazy(fn: () -> A): () -> A // ???
``````

### Exercise 4.5 solution

`myLazy` accepts a lambda expression of type `() -> A` as an input parameter. It’s also important to note that `A` has a constraint, which makes it non-null. This makes the exercise a little bit easier, because you can write something like:

``````fun <A : Any> myLazy(fn: () -> A): () -> A {
var result: A? = null // 1
return { // 2
if (result == null) { // 3
result = fn() // 4
}
result!! // 5
}
}
``````
``````fun main() {
val myLazy = myLazy { println("I'm very lazy!"); 10 }
3.times {
println(myLazy())
}
}
``````
``````I'm very lazy!
10
10
10
``````

## Exercise 4.6

Create a function `fibo` returning the values of a Fibonacci sequence. Remember, every value in a Fibonacci sequence is the sum of the previous two elements. The first two elements are `0` and `1`. The first values are, then:

``````0  1  1  2  3  5  8  13  21 ...
``````

### Exercise 4.6 solution

The following is a possible implementation for the Fibonacci sequence using lambda evaluation:

``````fun fibo(): () -> Int {
var first = 0
var second = 1
var count = 0
return {
val next = when (count) {
0 -> 0
1 -> 1
else -> {
val ret = first + second
first = second
second = ret
ret
}
}
count++
next
}
}
``````
``````fun main() {
val fiboSeq = fibo()
10.times {
print("\${fiboSeq()}  ")
}
}
``````
``````0  1  1  2  3  5  8  13  21  34
``````

## Challenge 4.1

In Exercise 4.5, you created `myLazy`, which allowed you to implement memoization for a generic lambda expression of type `()-> A`. Can you now create `myNullableLazy` supporting optional types with the following signature?

``````fun <A> myNullableLazy(fn: () -> A?): () -> A? // ...
``````

### Challenge 4.1 solution

To remove the constraint, you just need to use an additional variable, like this:

``````fun <A> myNullableLazy(fn: () -> A?): () -> A? {
var evaluated = false // HERE
var result: A? = null
return { ->
if (!evaluated) {
evaluated = true
result = fn()
}
result
}
}
``````
``````fun main() {
val myNullableLazy: () -> Int? =
myNullableLazy { println("I'm nullable lazy!"); null }
3.times {
println(myNullableLazy())
}
}
``````
``````I'm nullable lazy!
null
null
null
``````

## Challenge 4.2

You might be aware of Euler’s number e. It’s a mathematical constant of huge importance that you can calculate in very different ways. It’s an irrational number like pi that can’t be represented in the form `n/m`. Here you’re not required to know what it is, but you can use the following formula:

### Challenge 4.2 solution

A possible implementation of the Euler formula is:

``````fun e(): () -> Double {
var currentSum = 1.0 // 1
var n = 1

tailrec fun factorial(n: Int, tmp: Int): Int = // 2
if (n == 1) tmp else factorial(n - 1, n * tmp)

return {
currentSum += 1.0 / factorial(n++, 1).toDouble() // 3
currentSum
}
}
``````
``````fun main() {
val e = e()
10.times {
println(e())
}
}
``````
``````2.0
2.5
2.6666666666666665
2.708333333333333
2.7166666666666663
2.7180555555555554
2.7182539682539684
2.71827876984127
2.7182815255731922
2.7182818011463845
``````
``````fun factSeq(): () -> Int {
var partial = 1
var n = 1
return {
partial *= n++
partial
}
}
``````
``````fun fastE(): () -> Double {
var currentSum = 1.0
val fact = factSeq()
return {
currentSum += 1.0 / fact().toDouble()
currentSum
}
}
``````
``````fun main() {
val e = fastE() // HERE
10.times {
println(e())
}
}
``````
``````2.0
2.5
2.6666666666666665
2.708333333333333
2.7166666666666663
2.7180555555555554
2.7182539682539684
2.71827876984127
2.7182815255731922
2.7182818011463845
``````
Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.