# C Appendix C: Chapter 3 Exercise & Challenge Solutions Written by Massimo Carli

Heads up... You're reading this book for free, with parts of this chapter shown beyond this point as scrambled text.

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

## Exercise 3.1

Is `inc` a pure function?

``````var count = 0

fun inc(x: Int): Int = ++count + x
``````

### Exercise 3.1 solution

In this case, `inc` is not a pure function because it increments a global variable that’s part of the external world. Incrementing `count` is a side effect. The function also doesn’t return the same value with the same input value, as you can verify by executing the following code:

``````fun main() {
println(inc(1))
println(inc(1))
println(inc(1))
println(inc(1))
}
``````
``````2
3
4
5
``````

## Exercise 3.2

Is `inc2` a pure function?

``````val count = 0

fun inc2(x: Int): Int = x + count + 1
``````

### Exercise 3.2 solution

This function isn’t so obvious, but it is pure because it always returns the same value in output for the same value in input. It uses `count`, which is part of the universe, but it’s a `val`, so it never changes. You can see `count` as part of the universe’s state but, because it’s immutable, it can’t be the consequence of any side effect, and it wont change the output.

## Exercise 3.3

Is `expr3`:

``````val expr3 = 42
val (a1, a2) = expr3 to expr3
``````
``````val (a1, a2) = 42 to 42
``````

### Exercise 3.3 solution

Yes, in this case, `expr2` is referentially transparent. You can prove this by running the following code without any exceptions:

``````fun main() {
// Expr3 is referentially transparent, as you can see here
val expr3 = { 42 }
val (a1, a2) = expr3() to expr3()
val expr3Eval = expr3()
val (a1Eval, a2Eval) = expr3Eval to expr3Eval
assertOrThrow("expr3 is not RT") {
a1 == a1Eval && a2 == a2Eval
}
}
``````

## Exercise 3.4

Suppose you have the following code:

``````val CounterIterator = object : Iterator<Int> {

private var count = 0

override fun hasNext(): Boolean = true

override fun next(): Int = count++
}
``````
``````val expr4 = { CounterIterator.next() }
``````

### Exercise 3.4 solution

In this case, `expr4` is not referentially transparent because the expression has a side effect.

``````fun main() {
// Expr4 is not referentially transparent, as you can see here
val expr4 = { CounterIterator.next() }
val (a1, a2) = expr4() to expr4()
val expr4Eval = expr4()
val (a1Eval, a2Eval) = expr4Eval to expr4Eval
assertOrThrow("expr4 is not RT") {
a1 == a1Eval && a2 == a2Eval
}
}
``````
``````Exception in thread "main" java.lang.AssertionError: expr4 is not RT
``````

## Exercise 3.5

The `Writer<A, B>` data type you defined earlier is a very important concept in functional programming. If you use types as objects and the functions `Writer<A, B>` as morphisms, you get a very special category: the Kleisli category.

``````typealias Writer<A, B> = (A) -> Pair<B, String>
``````

### Exercise 3.5 solution

In Chapter 2, “Function Fundamentals”, you learned that some objects with arrows between them, known as morphisms, form a category if all the following rules are true:

#### Proving composition

In this case, you have to prove that for every morphism `f` from the objects `A` to `B`, and `g` from `B` to `C`, there’s always a morphism `g◦f` from `A` to `C`, which is the composition of `f` with `g`.

``````infix fun <A, B, C> Writer<B, C>.after(
w: Writer<A, B>
): Writer<A, C> = { a: A ->
val (b, str) = w(a)
val (c, str2) = this(b)
c to "\$str\n\$str2\n"
}
``````
``````infix fun <A, B, C> Writer<A, B>.compose(
w: Writer<B, C>
): Writer<A, C> = w after this
``````

#### Proving associativity

To prove associativity for `Writer<A, B>`, you basically need to prove that:

``````(h after g) after f == h after (g after f)
``````
``````f: Writer<A, B>
g: Writer<B, C>
h: Writer<C, D>
``````
``````(str1 + str2) + str3 == str1 + (str2 + str3)
``````

#### Proving identity

In this case, you need to prove that for every type `A`, there’s always a morphism `Writer<A, A>` called identity `id<A>`, such that, for every `f` of type `Writer<A, B>` the following is true:

``````f after id == id after f == f
``````
``````fun <A, B> Fun<A, B>.liftW(
log: (A, B) -> String
): Writer<A, B> =
{ a: A ->
val b = this(a)
b to log(a, b)
}
``````
``````fun <A> identity(a: A) = a
``````
``````fun <A> id(): Writer<A, A> = { a -> a to "" }
``````
``````f after id == id after f == f
``````
``````infix fun <A, B, C> Writer<B, C>.after(
w: Writer<A, B>
): Writer<A, C> = { a: A ->
val (b, str) = w(a)
val (c, str2) = this(b)
c to "\$str\n\$str2\n"
}
``````
``````f after id
``````
``````fun <A, C> Writer<A, C>.after(): Writer<A, C> = { a: A ->
val (b, str) = id<A>()(a)
val (c, str2) = this(b)
c to "\$str\n\$str2\n"
}
``````
``````str = ""
b = a
c = f(b) = f(a)
"\$str\n\$str2\n" = "\$str2\n"
``````
``````f(a) to "\$str2\n"
``````
``````id after f
``````
``````infix fun <A, C> Writer<A, C>.after(
w: Writer<A, C>
): Writer<A, C> = { a: A ->
val (b, str) = w(a)
val (c, str2) = id<C>()(b)
c to "\$str\$str2\n"
}
``````
``````val (b, str) = f(a)
c = id(b) = b to "\$str\n"
``````
``````f(a) to "\$str\n"
``````

## Challenge 1: Pure or impure?

Is `inc3` a pure function? Why or why not?

``````var count = 0
fun inc3(x: Int): Int {
val result = x + ++count + 1
println("Res: \$result") // WHAT IF YOU REMOVE THIS?
--count
return result
}
``````

### Challenge 1 solution

The answer, in this case, isn’t so obvious. Every time you invoke `inc3`, you calculate a result incrementing `count`, a global variable. You then print the result and decrement the global variable `count` before returning the result. `println` makes this function impure.

## Challenge 2: Pure or impure?

Is `output` a pure function? Why or why not?

``````fun output(x: Int): Unit = println("x = \$x")
``````

### Challenge 2 solution

This function always provides the same output, `Unit`, for the same input. The problem is that it logs messages, so it has side effects. Because of this, `output` is not a pure function.

## Challenge 3: Pure or impure?

Is `randomAdd` a pure function? Why or why not?

``````fun randomAdd(a: Int, b: Int): Int = a + b + Random.nextInt()
``````

### Challenge 3 solution

This function doesn’t provide the same output for the same input values because of the `Random` component. What about side effects? Even if it’s not directly visible, this function has a side effect: It changes the state of the `Random` object.

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.

© 2022 Razeware LLC You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription. 