El tipe class monoid es cats.kernel.Monoid, que tiene el alias cats.Monoid. Monoid extiende cats.kernel.Semigroup, que tiene el alias de cats.Semigroup. Cuando usamos Cats, normalmente importamos estas clases :
import cats.Monoid
import cats.Semigroup
Monoid sigue el patrón Cats estándar: el objeto complementario tiene un método de aplicación que devuelve la instancia del type class para un tipo en particular. Por ejemplo, si queremos la instancia monoide para String y tenemos los implícitos correctos en el alcance, podemos escribir lo siguiente:
import cats.Monoid
import cats.instances.string._ // for Monoid
Monoid[String].combine("Hi ", "there")
// res0: String = "Hi there"
Monoid[String].empty
// res1: String = ""
que es equivalente a:
Monoid.apply[String].combine("Hi ", "there")
// res2: String = "Hi there"
Monoid.apply[String].empty
// res3: String = ""
Como sabemos, Monoid extiende Semigroup. Si no necesitamos empty, podemos escribir de manera equivalente:
import cats.Semigroup
Semigroup[String].combine("Hi ", "there")
// res4: String = "Hi there"
Las instancias de clase de tipo para Monoid se organizan en cats.instances de la manera estándar. Por ejemplo, si queremos obtener instancias para Int, las importamos cats.instances.int:
import cats.Monoid
import cats.instances.int._ // for Monoid
Monoid[Int].combine(32, 10)
// res5: Int = 42
De manera similar, podemos ensamblar un Monoid[Option[Int]] usando instancias de cats.instances.int y cats.instances.option:
import cats.Monoid
import cats.instances.int._
// for Monoid
import cats.instances.option._ // for Monoid
val a = Option(22)
// a: Option[Int] = Some(22)
val b = Option(20)
// b: Option[Int] = Some(20)
Monoid[Option[Int]].combine(a, b)
// res6: Option[Int] = Some(42)
Como siempre, a menos que tengamos una buena razón para importar instancias individuales, podemos importar todo.
import cats._
import cats.implicits._