/scala-with-cats

Primary LanguageScalaMIT LicenseMIT

Scala with cats

Learning cats along with Scala with Cats

Chapter1

Type class is a design pattern that encapsulates the implementation to process a type T value. It roughly consists of three components: Type class, Type class instances and interface method. Interface method takes both type T value and an instance of the type class as its arguments and decouples concrete implementation to process type T value as a type class instance. So users can use the method to any type T by supplying type class instances to its implicit scope.

implicit resolution of invariance, variance and contravariance

Type Class Variance Invariant Covariant Contravariant
Supertype instance used? No No Yes
More specific type preferred? No Yes No

Chapter2

Monoid is a type class that has following properties.

  1. (A, A) => A
  2. associative
  3. has identity element

1. means that Monoid is closed, that means it takes two arguments of the same type (A in above) and produces a result that is also the same type of arguments.

Semigroup is a type class that has following properties

  1. (A, A) => A
  2. associative

Comparing with Monoid, Semigroup does not have any identity element. Conversely, Monoid is also Semigroup.

For instances, NonEmptyList and PositiveNumber does not have identity element so that it is Semigroup but not Monoid These properties are useful when combining values produced in parallel execution because their completion order is no matter.

Chapter3

A Functor is a type class taking type constructor as its type parameter that transform an element of type A into type B within the context. Functor F[A] has the following property.

  1. (A => B) => F[B]

Thus, functor chains sequential operations within the closed context.

Type Constructor

A type constructor is a constructor that produce regular type by being filled a type placeholder. List is a type constructor that can produce regular type List[Int] by filling a placeholder with Int.

Contravariant Functor has the contramap that prepends an operation.

  1. (B => A) => F[B]

When given the map function B => A, it can be prepended all methods in F[B] thus F[B] can be instantiated. any methods m of F[B] can be implemented using map function f: B => A as f andThen m.

B => A means B is subtype of A. It produces F[B] from F[A] i.e. F[A] => F[B], F[B] is regarded as subtype of F[A]. Therefore it fills covariant's relationship.

Invariant Functor has the imap that transform A in bidirection.

  1. (A <=> B) => F[B]

Chapter4

A Monad is a type class taking type constructor as its type parameter. Similar to Functor, it sequences computing but it can also begin new computing sequence on the middle of another sequence. Monad has following properties:

  1. pure: A => F[A]
  2. flatMap: (F[A])(A => F[B]) => F[B]

Built-in Monads in Cats

  • MonadError
    • handle errors in monadic way
  • Eval
    • eager/lazy evaluation and memorization
  • Writer
    • separate I/O and computation
  • Reader
    • computation with a placeholder to inject dependencies
  • State
    • a function that transforms an input state to an output state and then computes a result.
cats Properties
val Now eager,memorized
def Always lazy, not memorized
lazy val Later lazy, memorized

Chapter5

MonadTransformer

A MonadTransformer wraps 2 nested Monads and provides reasonable flatMap definition according to inner Monad. In cats, MonadTransformers are conventionally defined as {name of Monad}T like OptionT.

Chapter6

Semigroupal

Semigroupal is a type class that takes 2 parameters typed F[A], F[B] and produce a tupled value within a context F[(A, B)]. It has following property:

  1. product: (F[A], F[B]) => F[(A, B)]

Built-in Semigroupal in Cats

  • Validated
    • accumulate left value by combining them using Semigroup
  • ValidatedNel
    • Validated with NonEmptyList as its left values.

Apply

Apply extends Semigroupal and Functor so it has following properties:

  1. product: (F[A], F[B]) => F[(A, B)]
  2. ap: (F[A => B])(F[A]) => F[B]

Applicative Functor

Applicative Functor extends Apply and has pure so it has following properties:

  1. product: (F[A], F[B]) => F[(A, B)]
  2. ap: (F[A => B])(F[A]) => F[B]
  3. pure: A => F[A]

Hierarchy

Refer to Cats infographic

Chapter7

Foldable

Foldable is a type class that have foldLeft and foldRight that are flexible way to iterate elements in a context and returning a result.

  1. foldLeft: (F[A], B)((B, A) => B) => B
  2. foldRight: (F[A], B)((A, B) => B) => B

Traverse

Traverse is more formulated than Foldable that it combines the result by Applicative#product.

  1. traverse: (F[A])(A => G[B]): G[F[B]]
  2. sequence: (F[G[B]]): G[F[B]]