Functional Programming with Kotlin and Arrow: Getting Started

In this tutorial, you will learn the fundamentals of functional programming and how various Kotlin language features enable functional programming concepts. By Massimo Carli.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 4 of 4 of this article. Click here to view the first page.

Logger: The FP Way

In the previous code, you used functions that were not pure with a shared state and a side effect. How can you make the same functions pure and safe in a multithreaded environment?

Everything a pure function does must use its parameters, so the logger version of your example must be one of those. Think of FP as a superhero with two special powers: abstraction and composition. This code is all you need:

Start a new file with the name FPLogger.kt and define this first abstraction:

typealias Writer<T, R> = (T) -> Pair<R, String>

The Writer type abstracts functions from a generic type T to a type Pair<R, String>, where the second parameter is the content of the log to append. This is very powerful because you can now write these functions:

val fpGetPrice: Writer<Book, Price> =
  fun(book: Book) = getPrice(book) to "Price calculated for ${book.ISDN}"

val fpFormatPrice: Writer<Price, String> =
  fun(price: Price) = formatPrice(price) to "Bill line created for ${formatPrice(price)}"

They are now functions of the same generic type Writer<T,R>.

Now you need to define what composition means for your new abstraction. Define the compose function like this:

infix fun <A, B, C> Writer<A, B>.compose(f: Writer<B, C>): Writer<A, C> =
  { x: A ->
    val p1 = this(x)
    val p2 = f(p1.first)
    p2.first to p1.second + "\n" + p2.second
  }

Think of the type Writer<T, R> as the union of two different functions. The first maps elements in T into elements in R. The second maps the result of type R into a String. The first component of the resulting type is then the normal composition of two functions. The second component is the composition of two strings.

Test the result using this code:

fun main() {
  // We compose the functions
  val getPriceWithLog = fpGetPrice compose fpFormatPrice
  books.forEach { book ->
    println(getPriceWithLog(book).second)
  }
}

Build and run getting an output like this:

Price calculated for 8850333404
Bill line created for value: 39.26£
Price calculated for 8850330731
Bill line created for value: 40.06£
Price calculated for 885033334X
Bill line created for value: 34.03£
Price calculated for B00BVBVSZ8
Bill line created for value: 3.99£
Price calculated for 885033222X
Bill line created for value: 55.2£
Price calculated for B00FED9XQ0
Bill line created for value: 4.49£
Price calculated for 885033222X
Bill line created for value: 4.49£
Price calculated for 8850330103
Bill line created for value: 30.54£

What About Arrow?

Category Theory inspired this tutorial series in order to promote functional programming. That is also the motivation for the creation of the Arrow library, which defines a set of APIs to apply FP concepts like the composition you saw earlier.

You’ll study many Arrow constructs in future tutorials, but as a first step, you can use composition though the compose function after adding these dependencies in the build.gradle file in the dependencies section:

    def arrow_version = "0.9.0"
    compile "io.arrow-kt:arrow-core:$arrow_version"
    compile "io.arrow-kt:arrow-syntax:$arrow_version"

Now, use the compose function to rewrite the example from Composition.kt in a new Arrow.kt file:

import arrow.core.compose

fun main() {
  val compositeResult: String = (formatPrice compose getPrice)(books[0])
  println(compositeResult)
}

If you build and run you get this output which proves how the Arrow’s compose function works:

value: 39.26£

Where to Go From Here?

Now that you have a deep understanding of the fundamentals of FP, abstraction and composition, you can start playing with the Arrow framework. Use the Download Materials button at the top or bottom of the tutorial to access the final version of the code.

This is just the beginning! Keep practicing. Check out Bartosz Milewski’s video Category Theory for Programmers course for more details on category theory.

If you have any questions or comments, please join the discussion below!

Massimo Carli

Contributors

Massimo Carli

Author

Nick Winegar

Tech Editor

Nicole Hardina

Editor

Luke Freeman

Illustrator

Namrata Bandekar

Final Pass Editor

Eric Soto

Team Lead

Over 300 content creators. Join our team.