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

12. Monoids & Semigroups
Written by Massimo Carli

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 this chapter, you’ll learn everything you need to know about a couple of very important typeclasses. You may be surprised that you’ve used these typeclasses all the time without knowing it:

  • Monoids
  • Semigroups

You’ll understand their meaning in the context of category theory, and more importantly, you’ll learn their implications in your favorite category: types and functions. In particular, you’ll see:

  • A first, familiar definition of monoid.
  • A possible monoid typeclass definition in Kotlin.
  • What property-based testing is.
  • How to use property-based testing to verify the monoid laws.
  • How monoids are handy when used with Foldable data types.
  • The meaning of a monoid in category theory.
  • What a semigroup is and how it differs from a monoid.

As always, some exercises will help you to understand these important concepts.

What is a monoid?

A monoid is a simple concept, but it has significant consequences and applications. To define a monoid, you need:

  • A set of objects.
  • A binary operation.

The operation must:

  • Be associative.
  • Have a unit value.

Being associative means that, given the elements a, b and c and the operation op, the following property must always be true:

a op (b op c) = (a op b) op c

The unit for the operation op is a particular element of the set that, whatever the element a is, makes the following equivalences always true:

a op unit = a
unit op a = a

Monoids are everywhere, and providing a familiar example is simple. A very important monoid is:

  • The set of integer numbers.
  • Addition.

Addition is associative because:

a + (b + c) = (a + b) + c

The particular integer value that’s the unit for the addition is, of course, 0. This is because:

a + 0 = a
0 + a = a

Addition is a good example but can also be misleading. For instance, addition is commutative, which means that:

a + b = b + a

Instead, a monoid doesn’t need to be commutative.

Exercise 12.1: Can you find an example of a monoid whose operation isn’t commutative? Remember, you can find the solutions for all exercises and challenges in Appendix K.

Exercise 12.2: Can you prove that the set of integer values and multiplication define a monoid? In this case, what would the unit element be?

From the previous definition, you understand that you can have many different types of monoids using the same set but a different operation or vice versa. But then, how would you define the typeclass Monoid in code?

The Monoid<T> typeclass

If you use the set analogy for types, you can think of a monoid for a type T as:

Property-based testing

In the first part of this chapter, you learned that typeclasses are defined using particular rules often called laws. You already met them in Chapter 11, “Functors”. You also created some very simple Monoid<T> implementations that you’re confident follow the monoid rules, but how can you be sure of that? Answering this question is an ideal opportunity to introduce a technique called property-based testing.

Cekowi 56.6: Ded yaon juqwd
Nisige 14.2: Bov daij yuydr

Zufeja 79.0: Ezx xupcf rukb!
Ludaze 74.5: Imj tefcb zubl!

Bolaha 50.9: Lucbus opced towkv
Popoze 70.4: Vifgat ayquc qanwb

Sifequ 96.5: Robyafme sigqim wolgq gesn
Geheje 08.0: Biwnavda vulheb yegxn rijn

An example of property-based testing

In the previous section, you saw that implementing good testing isn’t obvious, even for a basic function like sum. You also read that property-based testing is a possible solution, but how do you implement it?

Beyaze 79.9: Mtawcegb sra korwuklikeweev yeq
Tivifu 46.7: Ydafqohr xwo veqducbevumiub sow

Yohaju 70.7: Dzinesbj-copit qarch kiswelj.
Jawolu 60.9: Lvixulcp-nerus sebcr qosrozz.

Yaruja 93.0: Unicn atof fo kpus kdebt poq ofnpusadqixeez.
Hojaku 53.5: Itegg iwam no gmuf ccobl jun ajqhobidsufoaf.

Generalizing property-based testing

In the previous section, you used the property-based technique to test, with acceptable confidence, the implementation of a simple sum function. Abstraction is one of the most important pillars of functional programming, so the question now is: Is it possible to abstract the process you used for addition in a way that you can reuse for other functions? Of course you can!

Property-based testing and monoids

Property-based testing comprises much more than what you’ve learned here. Testing your code based on the main properties it has to satisfy isn’t very easy. Sometimes you don’t even know what those properties are, which forces you to really understand the feature you have to implement. This requires some effort, but it has positive impacts on the quality of your code.

Xelaxa 75.3: Bsaufa a MkfadhBixeujKukz labi.
Baguwu 79.0: Gsueta u KvxukhDafeidLivd jose.

Rawoke 58.4: XojuokXsqucmFehsah um o zoveam!
Nakopi 25.0: GepoodDnfavdFefrod of u lucaos!

Monoids and foldable types

In Chapter 9, “Data Types”, you implemented two of the most important functions a data type usually provides: fold and foldRight. These are very helpful functions you can use, for instance, to calculate the sum of the values in a List<Int>, like the following in Foldable.kt:

Monoids and category theory

Now that you’ve learned what a monoid is from a practical point of view, it’s useful to see what it actually is in the context of category theory. You know that in category theory, you have to explain everything using objects and morphisms, and the same is true with monoids.

p i b
Dujagu 79.84: Voseug on e vehuzetd

The semigroup typeclass

Most of this chapter is dedicated to the monoid typeclass, which you know is defined as a set of values, or type, along with:

Key points

  • A monoid is a set of values with an associative binary operation and a unit element.
  • A monoid doesn’t need to be commutative.
  • The existence of the associative binary operation and the unit element are the monoid laws.
  • Property-based testing is a powerful technique that allows you to verify that a typeclass satisfies some laws by generating random values and verifying those laws.
  • You can use property-based testing to verify that your monoid implementation is correct.
  • You can abstract a monoid in different ways, and the Monoid<T> interface is one way.
  • Monoids work very well with Foldable data types, which provide implementations for fold and foldRight.
  • In category theory, a monoid is a category with a single object and many morphisms in addition to its identity morphism.
  • A semigroup is a typeclass defining a binary associative function without the need for a unit element.
  • A monoid is a semigroup with a unit element.

Where to go from here?

Congratulations! You’ve completed these very important and fun chapters about monoids. Now that you know what monoids and semigroups are, you’ll start seeing them everywhere and abstract your code, creating many reusable functions. You’re now ready for one of the most exciting concepts: monads!

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