I'm studying the 'Scala with Cats' book. I want the information to stick so I am applying a technique from 'Ultralearning' where I make revision notes in the questions which I regularly review. This post contains the questions and their answers.
Chapter 1: Introduction: Answers
- What is a type class?
- It’s a way of defining some behaviour that many types can adhere to. In scala it's a trait with a parameter
- What is an interface syntax in cats?
- What do Show and Eq do in cats?
- Members of show can be presented as strings.
- Explain covariance, contravariance and invariance.
- Covariance
- Contravariance
- Invariance F[A] and F[B] are never subtypes of each other, regardless of the relationship between A and B.
Chapter 2: Monoids and Semigroups: Answers
- Define monoid and semigroup and give examples of each.
Chapter 3: Functors: Answers
- What is a type constructor?
- A type constructor is like a type but it has a 'hole to fill'. Eg List is a type constructor because it has one 'hole' to fill. Note the difference between List (a type constructor) and List[A] (a type, using a type parameter) and List[Int] (a concrete type).
- What is a covariant functor?
- Write a method 'power' which can operate on either List(1,2,3) or Option(2) and returns List(1,4,9) and Option(4) respectively.
- What is a contravariant functor?
Chapter 4: Monads
- What is a monad?
- What is the 'Id' monad for?
- Imagine you have a method which operates on a Monad of Ints, eg power method so for Option(2) it returns Option(4) and for List(1,2) it returns List(1,4). To use this method on regular ints we need to wrap our plain Ints in a monad, hence Id.
- What is the 'Eval' monad for?
- This is for abstracting over different modes of computation, eager or lazy. Memoized computations run once then are cached, and can run lazily or eagerly. vals are eager and memoized. Defs are lazy and non memoized. Lazy vals are lazy and memoized. Eval has three subtypes, Now, Later and Always.
- It also has 'defer' which can be used to avoid stack overflow in recursive methods.
- What does each line print?
- 'Now' is eager and memoized (val). 'Later' is lazy and memoized (lazy val). 'Always' is lazy and not memoized (def).
- What is the output of the following code snippet and why?
- "Now" is calculated eagerly so is printed first. However mapping functions are always called like defs so the output is 'a, ---, b, c, Adding!, b, c, Adding!' There is a memoize function that can be used when chaining.
- What is the writer monad for?
- This is for carrying a log along with some computation. It's particularly useful in multithreaded computation where normal log messages might get interleaved. Writer[W,A] has a log of type W and a result of type A.
- What is the reader monad for?
- Reader[A,B] represents a function A => B. It allows sequencing of operations that depend on some input.
- What is the state monad for?
- The state monad allows us to pass additional state around as part of a computation. We can use it to model mutable state in a purely functional way, without the mutation. State[S, A] represents functions of type S => (S, A). S is the type of the state and A is the result type.
Chapter 5: Monad Transformers
- What are monad transformers used for?
- These are for composing monads, eg for giving us nice ways of handling Future[Option[T]]