Solutions to Scala with Cats: Chapter 7
April 5, 2023These are my solutions to the exercises of chapter 7 of Scala with Cats.
Table of Contents
- Exercise 7.1.2: Reflecting on Folds
- Exercise 7.1.3: Scaf-fold-ing Other Methods
- Exercise 7.2.2.1: Traversing with Vectors
- Exercise 7.2.2.2: Traversing with Options
- Exercise 7.2.2.3: Traversing with Validated
Exercise 7.1.2: Reflecting on Folds
If we use foldLeft with an empty list as the accumulator and :: as the
binary operator we get back the reversed list:
val list = List(1, 2, 3, 4)
list.foldLeft(List.empty[Int])((acc, e) => e :: acc)
// Returns List(4, 3, 2, 1).On the other hand, if we use foldRight with an empty list as the accumulator
and :: as the binary operator we get back the same list:
val list = List(1, 2, 3, 4)
list.foldRight(List.empty[Int])(_ :: _)
// Returns List(1, 2, 3, 4).Exercise 7.1.3: Scaf-fold-ing Other Methods
The following are implementations of the map, flatMap, filter and sum
methods for Lists in terms of foldRight:
def map[A, B](list: List[A])(f: A => B): List[B] =
list.foldRight(List.empty[B])((a, bs) => f(a) :: bs)
def flatMap[A, B](list: List[A])(f: A => List[B]): List[B] =
list.foldRight(List.empty[B])((a, bs) => f(a) ++ bs)
def filter[A](list: List[A])(f: A => Boolean): List[A] =
list.foldRight(List.empty[A])((a, as) => if (f(a)) a :: as else as)
def sum[A](list: List[A])(implicit numeric: Numeric[A]): A =
list.foldRight(numeric.zero)(numeric.plus)The sum method makes use of the Numeric type class from the Scala standard
library. In the spirit of this book, we could also have created an
implementation that uses the Monoid type class instead.
Exercise 7.2.2.1: Traversing with Vectors
The result of the provided expression is going to be a Vector of Lists, with
each being the pairwise combination of the elements from both Vectors:
Vector(
List(1, 3),
List(1, 4),
List(2, 3),
List(2, 4)
)If we use a list of three parameters, we will get back a Vector of Lists
again, but this time each list is going to be of three elements and we will have
one list per each possible triple combination of elements from each of the
Vectors:
Vector(
List(1, 3, 5),
List(1, 3, 6),
List(1, 4, 5),
List(1, 4, 6),
List(2, 3, 5),
List(2, 3, 6),
List(2, 4, 5),
List(2, 4, 6)
)Exercise 7.2.2.2: Traversing with Options
The return type of the process method is Option[List[Int]] and it will
return a Some of the provided input if all integers in the list argument are
even and None otherwise. Therefore, it will produce the following for the
first call:
Some(List(2, 4, 6))And the following for the second call:
NoneExercise 7.2.2.3: Traversing with Validated
The provided method will return a Valid with the list argument when all
integers of it are even or an Invalid with a List of String for each
element that is not even otherwise. Therefore, we get the following for the
first call:
Valid(List(2, 4, 6))And the following for the second call:
Invalid(List("1 is not even", "3 is not even"))