# Functional Programming With Kotlin and Arrow — Algebraic Data Types

**Kotlin 1.3, Other, IntelliJ IDEA**Kotlin 1.3, Other, IntelliJ IDEA

Learn how to use algebraic operations to better understand functional programming concepts like class constructs, typeclasses and lists in Kotlin & Arrow. By Massimo Carli.

### Sign up/Sign in

With a **free** Kodeco account you can download source code, track your progress,
bookmark, personalise your learner profile and more!

Already a member of Kodeco? Sign in

### Sign up/Sign in

With a **free** Kodeco account you can download source code, track your progress,
bookmark, personalise your learner profile and more!

Already a member of Kodeco? Sign in

### Sign up/Sign in

With a **free** Kodeco account you can download source code, track your progress,
bookmark, personalise your learner profile and more!

Already a member of Kodeco? Sign in

## Contents

## Functional Programming With Kotlin and Arrow — Algebraic Data Types

35 mins

- Getting Started
- What Is Algebra?
- Data Types and Multiplication
- Multiplying the Unit Type
- Multiplying the Nothing Type
- Multiplying Classes
- Data Types and Addition
- Understanding the Unit and Nothing Types
- Putting Algebra to Work
- Using Algebra for Type Safety
- Other Algebraic Properties
- Using Algebra With the Optional Type
- More Fun With Exponents
- Understanding Currying
- Carrying and the Flip Function
- Using Algebra With the List Type
- Functional Lists and Algebra
- Where to Go From Here?

Functional programming is magic, and in this tutorial, you’ll use simple algebraic operations to get a deeper understanding of the most important functional programming principles.

In the previous tutorial, Functional Programming with Kotlin and Arrow Part 4 – Generate Typeclasses With Arrow, you learned how to generate the code to implement important typeclasses like *Functor*, *Applicative* and *Monad*.

In this tutorial, you’ll build on that knowledge to learn:

- What algebra is and how it translates to the class construct and the
`Either<E, T>`

typeclass in Kotlin. - How and when algebraic data types are useful, including a common practical example.
- After addition and multiplication, you’ll see what the implications of exponents are.
- What a simple
*List<T>*has in common with algebra.

Understanding algebraic datatypes and how to use them will help you to master functional programming as they are very useful for encoding the business logic in applications.

Time to do some coding magic! :]

*Note*: The wonderful Bartosz Milewski’s Category Theory for Programmers course inspired this tutorial series. If you are new to Kotlin try Kotlin for Android: An Introduction to learn the fundamentals of Kotlin.

## Getting Started

Download the materials for this tutorial using the *Download Materials* button at the top or bottom of this page. Open the project using *IntelliJ 2019.x* or greater and you’ll see the following structure:

All the files are initially empty; it’ll be your job to add the code throughout this tutorial. But before writing any code, it’s important to understand the concept of *algebra*.

## What Is Algebra?

*Algebra* is a generalization of arithmetic that lets you combine numbers and letters representing numbers by using specific rules. Here’s an example of a simple *algebraic expression*:

```
a * X ^ 2 - b * X + c
```

In this example, you have numbers like the `2`

, letters like `a`

, `b`

and `c`

and operations like multiplication `*`

, addition `+`

and exponentiation `^`

.

Algebra is the set of rules that allow you to combine all those different symbols. But what does this have to do with Kotlin and functional programming?

Algebra and functional programming has a lot in common and programmers can use algebra to understand exactly how functional programming constructs work, starting with *product types*.

### Data Types and Multiplication

The Kotlin APIs define many classes, including `Pair<A, B>`

, which has the following simple code:

```
public data class Pair<out A, out B>(
public val first: A,
public val second: B
) : Serializable {
// ...
}
```

This class consists of a simple pair of values, the first of type `A`

and the second of type `B`

.

In the first tutorial of the series, Functional Programming with Kotlin and Arrow: Getting Started, you saw that a type is a way to represent all the possible values that a variable of that type can assume. For instance, a variable of type *Boolean* can contain the value `true`

or `false`

.

What about the `Pair<A, B>`

type? How many values are available for a variable of type `Pair<A, B>`

? To understand this, consider the type you’re defining by copying the following code into *Struct.kt*:

```
typealias BoolPair = Pair<Boolean, Boolean>
```

If you want to count all the possible values for a variable of type `BoolPair`

, simply add the following code:

```
val bool1 = Pair(true, true)
val bool2 = Pair(true, false)
val bool3 = Pair(false, true)
val bool4 = Pair(false, false)
```

From a pair of `Boolean`

variables, which you can consider as the value `2`

, you get `4`

values in total. But do you get those four values by adding `2+2`

or multiplying `2*2`

?

Answer this question by adding the following definition to the same file:

```
enum class Triage {
RED, YELLOW, GREEN
}
```

This defines the `Triage`

type, which is an `enum`

with three different values: `RED`

, `YELLOW`

and `GREEN`

. Next, add the following code:

```
typealias BoolTriage = Pair<Boolean, Triage>
```

This defines a `Pair`

consisting of a `Boolean`

and a `Triage`

. Now, repeat the same question: How many values does this type have?

To find out, simply use the following code:

```
val triple1 = Pair(true, Triage.RED)
val triple2 = Pair(true, Triage.YELLOW)
val triple3 = Pair(true, Triage.GREEN)
val triple4 = Pair(false, Triage.RED)
val triple5 = Pair(false, Triage.YELLOW)
val triple6 = Pair(false, Triage.GREEN)
```

which proves that the possible values are:

```
Boolean * Triage = 2 * 3 = 6
```

This brings you to the conclusion that a `Pair<A, B>`

has as many values as the product of multiplying the values of `A`

by the values of `B`

.

Now take a look at what happens when incorporating the *Unit* type into the multiplication.

### Multiplying the Unit Type

In the first tutorial of this series, you learned that the `Unit`

type has a single instance with the same name `Unit`

. In *Struct.kt*, add the following definition:

```
typealias UnitTriage = Pair<Unit, Triage>
```

Now, note that the number of possible values is the value you get by adding the following code to the same file:

```
val unit1 = Pair(Unit, Triage.RED)
val unit2 = Pair(Unit, Triage.YELLOW)
val unit3 = Pair(Unit, Triage.GREEN)
```

You then have:

```
Unit * Triage = 1 * 3 = 3
```

This proves that the *Unit* is equivalent to the value `1`

when you multiply with it.

### Multiplying the Nothing Type

In the first tutorial of this series, you also learned about the `Nothing`

type, which is a type with no values. What happens if you add the following definition to *Struct.kt*?

```
typealias NothingTriage = Pair<Nothing, Triage>
```

When you try to add the following code, you’ll get an error. This is because you can’t have a value of type `Nothing`

so you can’t create an instance of the `NothingTriage`

type.

```
val nothing1 : NothingTriage = Pair(???, Triage.RED)
```

This means that the type `Nothing`

corresponds to the value *0* for multiplication purposes. In this case you can say that:

```
Nothing * Triage = 0 * 3 = 0
```

### Multiplying Classes

In the previous examples, you used `Pair<A, B>`

but what happens if you define a class, like so:

```
data class Struct(val enabled: Boolean, val triage: Triage, val value: Byte)
```

Based on what you learned in this paragraph, you can say that:

```
Struct = Boolean * Triage * Byte = 2 * 3 * 256 = 1536
```

The number of possible values is the product of multiplying all the values of the aggregated types. In this last example, `Byte`

has *256* values, so the total number of values is *1,536*.

But what happens when you do something like this instead:

```
data class Struct2(val enabled: Boolean, val triage: Triage, val name: String)
```

`String`

has many possible values, so you can’t determine an exact result — but having an exact result is also not important. As you’ll see later, the important thing is to understand that you can represent the relationship between types as a multiplication operation.