Cada método en Foldable está disponible en forma de sintaxis a través de cats.syntax.foldable. En cada caso, el primer argumento del método en Foldable se convierte en el receptor de la llamada al método:
import cats.syntax.foldable._ // for combineAll and foldMap
List(1, 2, 3).combineAll
// res12: Int = 6
List(1, 2, 3).foldMap(_.toString)
// res13: String = "123"
Recuerde que Scala solo usará una instancia de Foldable si el método no está explícitamente disponible en el receptor. Por ejemplo, el siguiente código usará la versión de foldLeft definida en List:
List(1, 2, 3).foldLeft(0)(_ + _)
// res14: Int = 6
mientras que el siguiente código genérico utilizará Foldable:
def sum[F[_]: Foldable](values: F[Int]): Int = values.foldLeft(0)(_ + _)
Por lo general, no necesitamos preocuparnos por esta distinción. ¡Es una característica! Llamamos al método que queremos y el compilador usa un Foldable cuando es necesario para garantizar que nuestro código funcione como se espera. Si necesitamos una implementación segura de pila de foldRight, usar Eval como acumulador es suficiente para obligar al compilador a seleccionar el método de Cats.