Cómo entender traverse, traverseU y traverseM


Estoy confundido sobre el caso de uso sobre traverse, traverseU y traverseM, lo busqué en el sitio web de scalaz, el simple ejemplo de código:

 def sum(x: Int) = x + 1

 List(1,2,3).traverseU(sum)

Parece Que es similar a (mapa y agregado):

List(1,2,3).map(sum).reduceLeft(_ + _)

Creo que es más que eso para traverseU, solo me pregunto cuál es la diferencia entre los 3 método, sería mejor que voy a tener un código de muestra para mostrar la diferencia

Muchas gracias de antemano

Author: Cloud tech, 2014-10-28

1 answers

sequence se utiliza para reunir aplicativo efectos. Más concretamente, te permite "voltear" F[G[A]] a G[F[A]], siempre que G sea Applicative y F sea Traversable. Así que podemos usarlo para "reunir" un montón de Applicative efectos (tenga en cuenta que todos los Monads son Applicative):

List(Future.successful(1), Future.successful(2)).sequence : Future[List[Int]]
// = Future.successful(List(1, 2))
List(4.set("abc"), 5.set("def")).sequence : Writer[String, List[Int]]
// = List(4, 5).set("abcdef")

traverse es equivalente a map entonces sequence, por lo que puede usarlo cuando tiene una función que devuelve un Applicative y desea obtener una sola instancia de su Applicative en lugar de una lista de {[28]]}

def fetchPost(postId: Int): Future[String]
//Fetch each post, but we only want an overall `Future`, not a `List[Future]`
List(1, 2).traverse[Future, String](fetchPost): Future[List[String]]

traverseU es la misma operación que traverse, solo con los tipos expresados de manera diferente para que el compilador pueda inferirlos más fácilmente.

def logConversion(s: String): Writer[Vector[String], Int] =
  s.toInt.set(Vector(s"Converted $s"))
List("4", "5").traverseU(logConversion): Writer[Vector[String], List[Int]]
// = List("4", "5").map(logConversion).sequence
// = List(4.set("Converted 4"), 5.set("Converted 5")).sequence
// = List(4, 5).set(Vector("Converted 4", "Converted 5"))

traverseM(f) es equivalente a traverse(f).map(_.join), donde join es el nombre de scalaz para flatten. Es útil como una especie de "mapa plano de elevación":

def multiples(i: Int): Future[List[Int]] =
  Future.successful(List(i, i * 2, i * 3))
List(1, 10).map(multiples): List[Future[List[Int]]] //hard to work with
List(1, 10).traverseM(multiples): Future[List[Int]]
// = List(1, 10).traverse(multiples).map(_.flatten)
// = List(1, 10).map(multiples).sequence.map(_.flatten)
// = List(Future.successful(List(1, 2, 3)), Future.successful(List(10, 20, 30)))
//     .sequence.map(_.flatten)
// = Future.successful(List(List(1, 2, 3), List(10, 20, 30))).map(_.flatten)
// = Future.successful(List(1, 2, 3, 10, 20, 30))
 63
Author: lmm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-19 11:35:08