Translate

martes, 20 de diciembre de 2022

Foldable y Traverse

La clase de tipo Foldable captura los métodos foldLeft y foldRight a los que estamos acostumbrados en secuencias como Lists, Vectors, y Streams. Usando Foldable, podemos escribir pliegues genéricos que funcionan con una variedad de tipos de secuencias. También podemos inventar nuevas secuencias y conectarlas a nuestro código.

Foldable nos brinda excelentes casos de uso para Monoids y la mónada Eval.

Comencemos con un resumen rápido del concepto general de plegado. Suministramos un valor acumulador y una función binaria para combinarlo con cada elemento de la secuencia:


def show[A](list: List[A]): String =

    list.foldLeft("nil")((accum, item) => s"$item then $accum")

show(Nil)

// res0: String = "nil"

show(List(1, 2, 3))

// res1: String = "3 then 2 then 1 then nil"


El método foldLeft funciona recursivamente en la secuencia. Nuestra función binaria se llama repetidamente para cada elemento, y el resultado de cada llamada se convierte en el acumulador de la siguiente. Cuando llegamos al final de la secuencia, el acumulador final se convierte en nuestro resultado final.

Dependiendo de la operación que estemos realizando, el orden en el que plegamos puede ser importante. Debido a esto, hay dos variantes estándar de pliegue:

  • foldLeft atraviesa de "izquierda" a "derecha" (de principio a fin);
  • foldRight atraviesa de "derecha" a "izquierda" (de fin a principio).

foldLeft y foldRight son equivalentes si nuestra operación binaria es asociativa.

Por ejemplo, podemos sumar List[Int] doblando en cualquier dirección, usando 0 como nuestro acumulador y la suma como nuestra operación pero no podemos hacer lo mismo con la resta :


List(1, 2, 3).foldLeft(0)(_ - _)

// res4: Int = -6

List(1, 2, 3).foldRight(0)(_ - _)

// res5: Int = 2