Translate

jueves, 31 de marzo de 2022

Monoides en Cats parte 3


Seguimos con monoides en cats.

Recordemos : 

• un Semigrupo representa una operación de suma o combinación;

• un monoide extiende un semigrupo agregando una identidad o un elemento "cero".

Podemos usar semigrupos y monoides importando tres cosas: las type class en sí, las instancias de los tipos que nos interesan y la sintaxis de semigrupo para darnos el operador |+| :

import cats.Monoid

import cats.instances.string._ // for Monoid

import cats.syntax.semigroup._ // for |+|

"Scala" |+| " with " |+| "Cats"

// res0: String = "Scala with Cats"

Con las instancias correctas en el alcance, podemos comenzar a agregar lo que queramos:

import cats.instances.int._ // for Monoid
import cats.instances.option._ // for Monoid

Option(1) |+| Option(2)
// res1: Option[Int] = Some(3)

import cats.instances.map._ // for Monoid

val map1 = Map("a" -> 1, "b" -> 2)
val map2 = Map("b" -> 3, "d" -> 4)
map1 |+| map2
// res2: Map[String, Int] = Map("b" -> 5, "d" -> 4, "a" -> 1)

import cats.instances.tuple._  // for Monoid
val tuple1 = ("hello", 123)
val tuple2 = ("world", 321)
tuple1 |+| tuple2
// res3: (String, Int) = ("helloworld", 444)

También podemos escribir código genérico que funcione con cualquier tipo para el que tengamos una instancia de Monoid:

def addAll[A](values: List[A])
(implicit monoid: Monoid[A]): A =
values.foldRight(monoid.empty)(_ |+| _)

addAll(List(1, 2, 3))
// res4: Int = 6

addAll(List(None, Some(1), Some(2)))
// res5: Option[Int] = Some(3)

Los monoides son una gran puerta de entrada a Cats. Son fáciles de entender y fáciles de usar. Sin embargo, son solo la punta del iceberg en términos de las abstracciones que Cats nos permite hacer.