# Solutions to "Scala with Cats": Chapter 10

April 8, 2023

These are my solutions to the exercises of chapter 10 of Scala with Cats.

## 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: