Chapters

Hide chapters

Functional Programming in Kotlin by Tutorials

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

Section I: Functional Programming Fundamentals

Section 1: 8 chapters
Show chapters Hide chapters

Appendix

Section 4: 13 chapters
Show chapters Hide chapters

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

In the first section of the book, you learned about the concept of type. In particular, you learned that a type for a variable is a way to represent the set of possible values you can assign to it. For instance, saying that a is an Int means you can assign only integer values to a. The same is true for more complex types like String or custom types like User and so on.

In this chapter, you’ll meet data types, another crucial concept that’s somewhat orthogonal to the concept of type. For instance, the Optional<T> data type is a classic example. It represents the concept of either having an object of type T or not, and doesn’t depend on what T actually is.

In particular, you’ll learn:

  • What a data type is.
  • How to define the Optional<T> data type.
  • The Optional<T> type in the context of data types.
  • What lift , map and flatMap functions are.
  • The common and important data types List<T> and Either<A, B>.
  • What the fold and foldRight functions are and why they’re useful.

As always, you’ll learn all this using the Kotlin language and some fun exercises and challenges.

What is a data type?

In the first section of the book, you learned the crucial definition of a type. You saw that a type is basically a way to represent a set of values you can assign to a variable or, in general, use in your program. Consider, for instance, the following code:

var a: Int = 10
var s: String = "Hello World!"
var b = true

Here, you can say that:

  1. a is a variable of type Int. This means you can assign only integer values to a.
  2. s is of type String, and you can assign any possible String you can create in Kotlin.
  3. You can assign to the Boolean variable b only a value of either true or false.

A type doesn’t just tell you what value you can assign but also what you can’t. In the previous code, you can’t assign true to a, for instance.

You also learned that types and functions together make a category, which is the pillar of composition.

A data type is a different concept that uses the previous types as type parameters. In general, you represent them as M<T> in the case of a single type parameter. Other data types have multiple parameters. For example, you represent a data type with two type parameters as M<A, B>.

As you’ll see, you can think of a data type as a container that provides some common functions so you can interact with its content. The best way to understand data types is by providing some examples, starting with a classic: Optional<T>.

The Optional<T> data type

As mentioned earlier, you can often think of a data type as a container that provides some context. Optional<T> is a classic example because it represents a container that can either:

Using Optional<T>

In OptionalTest.kt, add the following code:

Using lift, map and flatMap

In the previous example, you have strToInt, which is a function of type (String) -> Optional<T>. You want to compose this with double of type (Int) -> Int. Of course, you can’t, because double accepts an Int and strToInt provides an Optional<Int>. To solve this problem, you have two main options. The first is:

Uyreajox<Rflikj> Slbupw Efg Azgautab<Alq> Odsuomuk<Uhc> but pehUbCujua() yevy() ckowPoc
Jakuvo 5.3 - Vowd kefv Uglaikot<F>

Implementing map

Starting with the map function, you see that it receives a function of type Fun<A, B> as input and returns an Optional<B>. Remember that:

Implementing flatMap

While double is a Fun<Int, Int>, strToInt has type Fun<Int, Optional<Int>>, making it incompatible with map. You need something more. Add this code to Optional.kt:

Implementing getOrDefault

To ensure the previous code compiles, you also need to add getOrDefault to Optional.kt:

A quick review

In the previous section, you met three of the most critical concepts in functional programming. You’ll learn more about them in the following chapters. In particular, you learned:

The List<T> data type

So far, you’ve learned that you can think of a data type as a container with a specific context. The context of an Optional<T> is about something that can be there or not. Another fundamental data type is List<T>. In this case, the context is the ability to contain an ordered list of items. It’s important to say that Kotlin already provides the functions you implemented for Optional<T> and T?.

Folding

List<T> has a couple of magic functions that are very important and useful in the implementation of other functions. To see why, open Folding.kt and add the following code:

Folding right

Imagine you have a list of objects, and you want to group them together. To do this, you have two different options. You can:

What about FList<T>?

In Chapter 7, “Functional Data Structures”, you implemented FList<T> — whose code is available in FList.kt in this chapter’s material — as an example of a functional data structure. The existing of is equivalent to the lift function you learned here. It basically “lifts” the values you pass as a vararg to an FList<T>. Also, empty already provides the empty FList<T>. But what about fold, foldRight, map and flatMap?

Implementing fold and foldRight

In the previous section, you learned what fold and foldRight are, but you didn’t have any proof of how important these functions are. As a first step, you’ll implement fold and foldRight for FList<T>. Open FListExt.kt and add the following code:

Implementing map

map is one of the most crucial functions, and you’ll meet it many times when implementing your code. Its implementation is very simple. In FListExt.kt, add the following code:

Implementing flatMap

flatMap is probably the most challenging function to implement. It’s also part of the proof that fold and foldRight should be fundamental elements of your functional programming skills.

The Either<A, B> data type

Optional<T>, List<T> and FList<T> are examples of data types with a single type parameter. Life isn’t always so simple, however, and sometimes you need something more.

Implementing map

The most important and — fortunately — the easiest functionality to implement is map. But how can you provide a function of type Fun<A, B> if you don’t even know if Either<A, B> is Left<A> or Right<B>? The answer is very simple: You provide two. Add the following code to Either.kt:

Implementing accessors

If you think of every data type as a container, it’s often useful to define a function to get their content, like the getOrDefault function you met earlier. In this case, you can use different approaches. In Scala, for instance, the Either<A, B> type provides a getOrDefault only for the Right<B> value.

Implementing flatMap

As mentioned earlier, Either<A, B> is usually right-biased. This means you usually find functions like map and flatMap applicable to the Right<B> side of it, which usually represents success. Left<A> usually represents failure, and there’s not normally too much to do in this case. For this reason, you’ll implement flatMap for the Right<B> side. In Either.kt, add the following code:

Challenges

You’ve already done some interesting exercises dealing with data types. But here’s an opportunity to have some more fun with a few challenges.

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:

Challenge 9.2: Length

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

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.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?

Key points

  • A type is basically a way to represent a set of values you can assign to a variable or, in general, use in your program.
  • A data type is a way to represent a value in a specific context. You can usually think of a data type as a container for one or more values.
  • Optional<T> is a data type that represents a container that can be empty or contain a value of type T.
  • lift is the function you use to “elevate” a value of type T into a data type of M<T>.
  • map allows you to interact with a value in a data type applying a function. You’ll learn all about map in Chapter 11, “Functors”.
  • flatMap allows you to interact with a value in a data type M<T> using a function that also returns an M<T>. You’ll learn all about flatMap in Chapter 13, “Understanding Monads”.
  • List<T> is a data type that contains an ordered collection of values of type T.
  • fold and foldRight are magical functions you can use to implement many other functions.
  • The Either<A, B> data type allows you to represent a container that can only contain a value of type A or a value of type B.
  • You usually use Either<A, B> in the context of success or failure in the execution of a specific operation.
  • Either<A, B> has two type parameters. For this reason, it defines functions like bimap, leftMap and rightMap that you apply explicitly on one of the values.
  • Some data types with multiple parameters, like Either<A, B>, have functions that are biased on one of them. For instance, Either<A, B> is right-biased and provides functions that implicitly apply to its Right<B> side.

Where to go from here?

In this chapter, you had a lot of fun and implemented many important functions for the most important data type. In the following chapters, you’ll see even more data types and learn about functors and monads in more detail. In the next chapter, you’ll have some fun with math. Up next, it’s time to learn all about algebraic data types.

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.
© 2026 Kodeco Inc.

You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now