# Solutions to "Scala with Cats": Chapter 10

April 8, 2023These are my solutions to the exercises of chapter 10 of Scala with Cats.

## Table of Contents

- Exercise 10.3: Basic Combinators
- Exercise 10.4.2: Checks
- Exercise 10.4.3: Recap
- Exercise 10.5: Kleislis

## Exercise 10.3: Basic Combinators

The `and`

method of `Check`

will create a new `Check`

that calls `apply`

on both
instances. However, we soon hit the problem of what to do if they both return a
`Left`

:

We need a way to combine values of type `E`

, which hints towards the need for a
`Semigroup`

instance for `E`

. We’re assuming that we don’t want to short-circuit
but rather accumulate all errors.

For the `and`

implementation, we follow the algebraic data type style that is
recommended by the book:

`Validated`

is a more appropriate data type to accumulate errors than `Either`

.
We can also rely on the `Applicative`

instance for `Validated`

to avoid the
pattern match:

The `or`

combinator should return a `Valid`

if the left hand side is `Valid`

or
if the left hand side is `Invalid`

but the right hand side is `Valid`

. If both
are `Invalid`

, it should return an `Invalid`

combining both errors. Due to the
latter, we can’t rely on `orElse`

but rather have a slightly more complicated
implementation:

## Exercise 10.4.2: Checks

With our previous `Check`

renamed to `Predicate`

, we can implement the new
`Check`

with the proposed interface as follows, using an algebraic data type
approach as before:

`flatMap`

is a bit weird to implement because we don’t have a `flatMap`

for
`Validated`

. Fortunately, we have `flatMap`

in `Either`

and a `withEither`

method in `Validated`

that allows us to apply a function over an `Either`

that
gets converted back to a `Validated`

.

`andThen`

gets implemented very similarly to `flatMap`

, except that we don’t use
the output of the first `Check`

to decide which other `Check`

to use. The next
`Check`

is already statically provided to us:

## Exercise 10.4.3: Recap

The helper predicates that are introduced in this exercise make use of a `lift`

method on `Predicate`

that we haven’t implemented yet. Its implementation can be
something like the following:

A `Check`

for username can be implemented as follows, making use of the
`longerThan`

and `alphanumeric`

predicates.

A `Check`

for the email address can be implemented as follows. We first check
that the string contains at least one `@`

, then split the string, check each of
the sides and combine them back at the end:

## Exercise 10.5: Kleislis

The `run`

method on `Predicate`

must return a `A => Either[E, A]`

. We must rely
on the existing `apply`

method so we also need a `Semigroup`

instance for `E`

:

Our checks don’t change much. We have decided to implement the email address check slightly differently here, applying the checks directly in the split step: