Cats proporciona instancias para todas las mónadas en la biblioteca estándar (Option, List, Vector, etc.) a través de cats.instances:
import cats.instances.option._ // for Monad
Monad[Option].flatMap(Option(1))(a => Option(a*2))
// res0: Option[Int] = Some(2)
import cats.instances.list._ // for Monad
Monad[List].flatMap(List(1, 2, 3))(a => List(a, a*10))
// res1: List[Int] = List(1, 10, 2, 20, 3, 30)
import cats.instances.vector._ // for Monad
Monad[Vector].flatMap(Vector(1, 2, 3))(a => Vector(a, a*10))
// res2: Vector[Int] = Vector(1, 10, 2, 20, 3, 30)
Cats también proporciona una mónada para Future. A diferencia de los métodos de la propia clase Future, los métodos pure y flatMap de la mónada no pueden aceptar parámetros ExecutionContext implícitos (porque los parámetros no forman parte de las definiciones de la característica Monad). Para evitar esto, Cats requiere que tengamos un ExecutionContext en el alcance cuando invocamos una Monad para Future:
import cats.instances.future._ // for Monad
import scala.concurrent._
import scala.concurrent.duration._
val fm = Monad[Future]
// error: Could not find an instance of Monad for scala.concurrent.
Future
// val fm = Monad[Future]
//
^^^^^^^^^^^^^
Poner el ExecutionContext en el alcance corrige la resolución implícita requerida para invocar la instancia:
import scala.concurrent.ExecutionContext.Implicits.global
val fm = Monad[Future]
// fm: Monad[Future] = cats.instances.FutureInstances$$anon$1@7ba44cd6
La instancia de Monad usa el ExecutionContext capturado para llamadas posteriores a pure y flatMap:
val future = fm.flatMap(fm.pure(1))(x => fm.pure(x + 2))
Await.result(future, 1.second)
// res4: Int = 3
Además de lo anterior, Cats proporciona una gran cantidad de nuevas mónadas que no tenemos en la biblioteca estándar. Nos familiarizaremos con algunos de estos en un momento.