Scala is one of the most commercially successful programming languages in which functional programming is not only possible, but it is actively supported by language features, popular libraries, and many prominent advocates of functional programming.
One of the popular Library is Cats Library. It provides abstractions for functional programming in the Scala programming language.
3. Introduction
Cats is a library which provides abstractions for functional
programming in the Scala programming language.
The name is a playful shortening of the word category.
-Documentation
5. The Type Class
Type classes were first introduced in Haskell as a new approach to ad-hoc polymorphism.
Type classes in Haskell are based on Hindley–Milner type system.
Scala's type inference is based on Local Type Inference.
object Math {
trait NumberLike[A] {
def add(a: A, b: A): A
def subtract(a: A, b: A): A
def multiply(a: A, b: A): A
def divide(a: A, b: A): A
}
}
6. Type Class Instances
The instances of a type class provide implementations for the types.
Members of type classes are usually singleton objects.
implicit keyword before each of the type class implementations.
7. Type Class Instances [Example]
object Math {
trait NumberLike[A] {
def add(a: A, b: A): A
def subtract(a: A, b: A): A
def multiply(a: A, b: A): A
def divide(a: A, b: A): A
}
implicit val intLike: NumberLike[Int] = new
NumberLike[Int] {
override def add(a: Int, b: Int): Int = a + b
override def subtract(a: Int, b: Int): Int = a - b
override def multiply(a: Int, b: Int): Int = a * b
override def divide(a: Int, b: Int): Int = a / b
}
}
8. Type Class Interfaces
A type class interface is any functionality we expose to users.
object DoTheMath{
import Math.NumberLike
def addition[A](a: A, b: A)(implicit ev: NumberLike[A]) =
ev.add(a, b)
}
DoTheMath.addition(1,2)
9. Type class in Cats
Cats is written using a modular structure.
It allows us to choose which type classes, instances, and interface methods we want to use.
import cats.Show
import cats.instances.int._
val showInt: Show[Int] = Show.apply[Int]
val intToString: String = showInt.show(1)
import cats.syntax.show._
123.show
10. Defining Custom Instances
import java.util.Date
implicit val dateShow: Show[Date] =
Show.show(date => s"${date.getTime}ms since the epoch.")
dateShow.show(new Date())
Result:
res2: String = 1532873812098ms since the epoch.
11. trait Monoid[A] {
def combine(x: A, y: A): A
def empty: A
}
A monoid for a type A is:
an operation on combine with type (A, A) => A
an element empty of type A
Must follow associative law.
Must follow identity law.
Monoids
13. Semigroup
trait Semigroup[A] {
def combine(x: A, y: A): A
}
A semigroup is just the combine part of a monoid
For example NonEmptyList or Positive Integer
trait Monoid[A] extends Semigroup[A] {
def empty: A
}
14. Monoids and Semigroup in Cats
Type Class
The monoid type class is cats.kernel.Monoid , which is aliased as cats.Monoid.
Monoid extends cats.kernel.Semigroup , which is aliased as cats.Semigroup.
Instance
import cats.Monoid
import cats.instances.string._
Monoid[String].combine("Hello ", " World")
15. Monoids and Semigroup in Cats
Syntax
●Cats provides syntax for the combine method (|+| operator).
import cats.instances.option._
import cats.syntax.semigroup._
val result = Option(1) |+| Monoid[Option[Int]].empty
Result = Option(1)
16. Functors
A Functor is anything with a map method.
For example: Option , List , and Either
Functor as used to transforming the values inside. For example:
Option(1).map(_ + 1) // Option(2)
Result = Option(2)
17. Functors in Cats
Type Class
●The funtor type class is cats.Functor.
import cats.Functor
Functor[Option].map(Option(1))(_ + 2)
Instance
import cats.Functor
import cats.instances.option._
val optionIncrementFunc = Functor[Option].lift((x:Int) => x + 1)
val result = optionIncrementFunc(Option(2))
19. Monads
Monads are one of the most common abstractions in Scala.
A monad is anything with a constructor and a flatMap method.
All functors are monads.
A monad is a mechanism for sequencing computations.
Isn’t the functors are same as monads?
21. Monads in Cats
Type Class
The monad type class is cats.Monad.
import cats.Monad
Monad[Option].pure(3)
Instance
import cats.Monad
import cats.instances.option._
Monad[Option].flatMap(Option(3))(a => Some(a + 2))
// Option[Int] = Some(5)
23. Monads Transformation
Monad transformation in standard Scala library is difficult and messy.
Nested for-comprehension.
for {
optUser <- listOfUser
} yield {
for {
user <- optUser
} yield user.name
}
24. Cat Transformers
Cats provides transformers for many monads, each named with a T suffix.
EitherT composes Either with other monads, OptionT composes Option , and so on.
Each monad transformer is a data type, defined in cats.data.
cats.data.OptionT
cats.data.EitherT
cats.data.ReaderT
cats.data.WriterT
cats.data.StateT
cats.data.IdT