# I Appendix I: Chapter 9 Exercise & Challenge Solutions Written by Massimo Carli

You can unlock the rest of this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.

## Exercise 9.1

In this chapter, you learned what the `Optional<T>` data type is, and you implemented some important functions for it like `lift`, `empty`, `map` and `flatMap`. Kotlin defines its own optional type represented by `?`. How would you implement the `lift`, `empty` and `getOrDefault` functions for it?

### Exercise 9.1 solution

You can implement the previous functions like this:

``````fun <T : Any> T.lift(): T? = this // 1

fun <T : Any> T.empty(): T? = null // 2

fun <T : Any> T?.getOrDefault(defaultValue: T): T =
this ?: defaultValue // 3
``````
``````fun main() {
val optStr = "10".lift() // 1
optStr pipe ::println
val empty = String.empty() // 2
empty pipe ::println
optStr                     // 3
.getOrDefault("Default")
.pipe(::println)
empty                      // 4
.getOrDefault("Default")
.pipe(::println)
}
``````
``````10       // 1
null     // 2
10       // 3
Default  // 4
``````

## Exercise 9.2

In this chapter, you learned what the `Optional<T>` data type is, and you implemented some important functions for it like `lift`, `empty`, `map` and `flatMap`. Kotlin defines its own optional type represented by `?`. How would you implement the `map` and `flatMap` functions?

### Exercise 9.2 solution

A possible implementation of `map` for the Kotlin optional type is:

``````fun <A : Any, B : Any> A?.map(fn: Fun<A, B>): B? =
if (this != null) fn(this).lift() else null
``````
``````fun <A : Any, B : Any> A?.flatMap(fn: Fun<A, B?>): B? =
if (this != null) fn(this)?.lift() else null
``````

## Exercise 9.3

How would you replicate the example you implemented in OptionalTest.kt using `T?` instead of `Optional<T>`? Use the solutions of Exercise 9.1 and Exercise 9.2 to implement this example.

### Exercise 9.3 solution

You can test the code you created in Exercise 9.1 and Exercise 9.2 by running the following code:

``````fun strToInt(value: String): Int? = // 1
try {
value.toInt().lift()
} catch (nfe: NumberFormatException) {
null
}

fun <T : Any> T?.getOrDefault(defaultValue: T): T = // 2
if (this == null) defaultValue else this

fun main() {
"10" // 3
.lift()
.flatMap(::strToInt)
.map(::double)
.getOrDefault(-1)
.pipe(::println)

"10sa" // 4
.lift()
.flatMap(::strToInt)
.map(::double)
.getOrDefault(-1)
.pipe(::println)
}
``````
``````20
-1
``````

## Exercise 9.4

Implement a function that reverses a `String` using one of the folding functions you’ve implemented in this chapter.

### Exercise 9.4 solution

A `String` is just an array of `Char`s. This means that a possible implementation for the `reverse` function is:

``````fun reverse(str: String) =
str.toCharArray().toList() // 1
.declarativeFoldRight(StringBuilder()) { c, acc -> // 2
acc.append(c) // 3
acc
}.toString() // 4
``````
``````fun main() {
reverse("supercalifragilisticexpialidocious") pipe ::println
}
``````
``````suoicodilaipxecitsiligarfilacrepus
``````

## Exercise 9.5

In this chapter, you implemented `declarativeFold` and `declarativeFoldRight` as extension functions for `List<T>`. How would you implement them for `Iterable<T>`?

### Exercise 9.5 solution

The folding functions work for any ordered collection of items, so what really matters is the ability to iterate over them. A possible implementation for `declarativeFold` on `Iterable` is:

``````fun <T, S> Iterable<T>.iterableFold(
start: S,
combineFunc: (S, T) -> S
): S { // 1
tailrec fun helper(iterator: Iterator<T>, acc: S): S { // 2
if (!iterator.hasNext()) { // 3
return acc
}
return helper(iterator, combineFunc(acc, iterator.next())) // 4
}
return helper(iterator(), start) // 5
}
``````
``````fun <T, S> Iterable<T>.iterableFoldRight(
start: S,
combineFunc: (T, S) -> S
): S {
fun helper(iterator: Iterator<T>): S {
if (!iterator.hasNext()) {
return start
}
return combineFunc(iterator.next(), helper(iterator))
}
return helper(iterator())
}
``````
``````fun main() {
"supercalifragilisticexpialidocious".asIterable()
.iterableFoldRight(StringBuilder()) { item, acc ->
acc.append(item)
acc
} pipe ::println
"supercalifragilisticexpialidocious".asIterable()
.iterableFold(StringBuilder()) { acc, item ->
acc.append(item)
acc
} pipe ::println
}
``````
``````suoicodilaipxecitsiligarfilacrepus
supercalifragilisticexpialidocious
``````

## Challenge 9.1: Filtering

How would you implement a `filter` function on a `List<T>` using `fold` or `foldRight`? You can name it `filterFold`. Remember that given:

``````typealias Predicate<T> = (T) -> Boolean
``````
``````fun <T> List<T>.filterFold(predicate: Predicate<T>): List<T> {
// Implementation
}
``````

### Challenge 9.1 solution

You know that `fold` allows you to basically recreate a collection of items. If you add an item after the evaluation of a predicate, you basically implement the `filter` function. One possible solution is:

``````fun <T> List<T>.filterFold(predicate: Predicate<T>): List<T> =
fold(mutableListOf()) { acc, item -> // 1
if (predicate(item)) { // 2
}
acc
}
``````
``````fun main() {
listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
.filterFold { it % 2 == 0 }
.forEach(::println)
}
``````
``````2
4
6
8
10
``````

## Challenge 9.2

How would you implement the `length` function for a `List<T>` that returns its size using `fold` or `foldRight`?

### Challenge 9.2 solution

A possible implementation is:

``````fun <T> List<T>.length(): Int =
fold(0) { acc, _ ->
acc + 1
}
``````
``````fun main() {
val list = List<Int>(37) { it }
list.length() pipe ::println
}
``````
``````37
``````

## Challenge 9.3: Average

How would you implement the `avg` function for a `List<Double>` that returns the average of all the elements using `fold` or `foldRight`?

### Challenge 9.3 solution

The solution here is simple, and is basically the implementation of the definition of average: the sum of all the elements divided by the number of elements:

``````fun List<Double>.average(): Double =
fold(0.0) { acc, item -> acc + item } /
fold(0.0) { acc, _ -> acc + 1 }
``````
``````fun main() {
val list = List<Int>(37) { it }
list.average() pipe ::println
}
``````
``````18.0
``````

## Challenge 9.4: Last

How would you implement the `lastFold` function for a `List<T>` that returns the last element using `fold` or `foldRight`? What about `firstFold`?

### Challenge 9.4 solution

One possible implementation is:

``````fun <T> List<T>.lastFold(): T? =
fold(null as T?) { _, item -> item }
``````
``````fun main() {
val list = List<Int>(37) { it }
list.lastFold() pipe ::println
val empty = emptyList<Int>()
empty.lastFold() pipe ::println
}
``````
``````36
null
``````
``````fun <T> List<T>.firstFold(): T? =
foldRight(null as T?) { item, acc -> item }
``````
``````val list = List<Int>(37) { it }
list.firstFold() pipe ::println
``````
``````0
``````

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.