En la entrada anterior, Monocle IV: lente Prism, realicé una descripción de la lente Prism, así como, la descripción de unos ejemplos de uso. En la presente entrada, Monocle V: lente Traversal, me centraré en la lente Traversal.
La lente Traversal es aquella lente que generaliza la lente Optional. El ejemplo común de Traversal es poner el foco en todos los elementos de un contenedor de tipo List, Vector u Option.
La lente Traversal relaciona las typeclasses Traverse y Traversal de la librería Scalaz.
Para los ejemplos, definiremos los siguientes contenedores e importaciones de elementos siguientes:
import monocle.Traversal import scalaz.std.list._ val xs = List(1,2,3,4,5) val ys = List.empty[Int]
Definición de la lente Traversal
La definición de la lente Traversal de ejemplo es la siguiente:
val eachL = Traversal.fromTraverse[List, Int]
Operaciones básicas
Operación Set
Para la asignación de un valor a todos los elementos, se utiliza la función set de la siguiente manera:
println(s"1.- eachL.set(69)(List(1,2,3,4,5))= ${eachL.set(69)(xs)} ") println(s"2.- eachL.set(69)(List.empty[Int])= ${eachL.set(69)(ys)} ")
La salida por consola es la siguiente:
1.- eachL.set(69)(List(1,2,3,4,5))= List(69, 69, 69, 69, 69) 2.- eachL.set(69)(List.empty[Int])= List()
Operación Get
Para la obtención de todos los elementos existentes en la lente Traversal, se utiliza la función getAll de la siguiente manera:
println(s"5.- eachL.getAll(List(1,2,3,4,5))= ${eachL.getAll(xs)} ") println(s"6.- eachL.getAll(List.empty[Int])= ${eachL.getAll(ys)} ")
La salida por consola es la siguiente:
5.- eachL.getAll(List(1,2,3,4,5))= List(1, 2, 3, 4, 5) 6.- eachL.getAll(List.empty[Int])= List()
Operación Modify
Para la modificación de todos los elementos de la lente Traversal, se utiliza la función modify de la siguiente manera:
println(s"3.- eachL.modify(_ + 1)(List(1,2,3,4,5))= ${eachL.modify(_ + 1)(xs)} ") println(s"4.- eachL.modify(_ + 1)(List.empty[Int])= ${eachL.modify(_ + 1)(ys)} ")
La salida por consola es la siguiente:
3.- eachL.modify(_ + 1)(List(1,2,3,4,5))= List(2, 3, 4, 5, 6) 4.- eachL.modify(_ + 1)(List.empty[Int])= List()
Otras operaciones
Para la obtención de la cabecera de un contenedor de una lente Traversal, se utiliza la función headOption; para buscar un elemento en función de una posición, se emplea la función find; y, para aplicar una función a todos los elementos de la lente, se emplea la función all. Unos ejemplos de las funciones descritas son los siguientes:
println(s"5.- eachL.headOption(List(1,2,3,4,5))= ${eachL.headOption(xs)} ") println(s"6.- eachL.headOption(List.empty[Int])= ${eachL.headOption(ys)} ") println(s"7.- eachL.find(_ > 3)(List(1,2,3,4,5))= ${eachL.find(_ > 3)(xs)} ") // OJO! Retorna el elemento siguiente a 3 println(s"8.- eachL.find(_ > 3)(List.empty[Int])= ${eachL.find(_ > 3)(ys)} ") println(s"9.- eachL.all(_ % 2 == 0)(List(1,2,3,4,5))= ${eachL.all(_ % 2 == 0)(xs)} ") println(s"10.- eachL.all(_ % 2 == 0)(List.empty[Int])= ${eachL.all(_ % 2 == 0)(ys)} ") // OJO! Retorna true y la lista es vacía.
La salida por consola es la siguiente:
5.- eachL.headOption(List(1,2,3,4,5))= Some(1) 6.- eachL.headOption(List.empty[Int])= None 7.- eachL.find(_ > 3)(List(1,2,3,4,5))= Some(4) 8.- eachL.find(_ > 3)(List.empty[Int])= None 9.- eachL.all(_ % 2 == 0)(List(1,2,3,4,5))= false 10.- eachL.all(_ % 2 == 0)(List.empty[Int])= true
Para el lector interesado, las entradas que he realizado sobre el tema son las siguientes:
- Monocle I: introducción y lente Iso
- Monocle II: lente Lens
- Monocle III: lente Optional
- Monocle IV: lente Prism
- Monocle V: lente Traversal