Solutions to Scala with Cats: Chapter 2
April 3, 2023These are my solutions to the exercises of chapter 2 of Scala with Cats.
Table of Contents
- Exercise 2.3: The Truth About Monoids
- Exercise 2.4: All Set for Monoids
- Exercise 2.5.4: Adding All the Things
Exercise 2.3: The Truth About Monoids
For this exercise, rather than defining instances for the proposed types, I
defined instances for Cats’ Monoid
directly. For that purpose, we need to
import cats.Monoid
.
For the Boolean
type, we can define 4 monoid instances. The first is boolean
or, with combine
being equal to the application of the ||
operator and
empty
being false
:
The second is boolean and, with combine
being equal to the application of the
&&
operator and empty
being true
:
The third is boolean exclusive or, with combine
being equal to the application
of the ^
operator and empty
being false
:
The fourth is boolean exclusive nor (the negation of exclusive or), with
combine
being equal to the negation of the application of the ^
operator and
empty
being true
:
To convince ourselves that the monoid laws hold for the proposed monoids, we can
verify them on all instances of Boolean
values. Since they’re only 2 (true
and false
), it’s easy to check them all:
Exercise 2.4: All Set for Monoids
Set union forms a monoid for sets:
Set intersection only forms a semigroup for sets, since we can’t define an
identity element for the general case. In theory, the identity element would be
the set including all instances of the type of elements in the set, but in
practice we can’t produce that for a generic type A
:
The book’s solutions suggest an additional monoid (symmetric difference), which didn’t occur to me at the time:
Exercise 2.5.4: Adding All the Things
The exercise is clearly hinting us towards using a monoid, but the first step
can be defined in terms of Int
only. The description doesn’t tell us what we
should do in case of an empty list, but, since we’re in a chapter about monoids,
I assume we want to return the identity element:
Changing the code above to also work with Option[Int]
and making sure there is
no code duplication can be achieved by introducing a dependency on a Monoid
instance:
With the above in place we continue to be able to add Int
s, but we’re also now
able to add Option[Int]
s, provided we have the appropriate Monoid
instances
in place:
To be able to add Order
instances without making any modifications to add
,
we can define a Monoid
instance for Order
. In this case, we’re piggybacking
on the Monoid
instance for Double
, but we could’ve implemented the sums and
the production of the identity element directly: