Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to understand traverse, traverseU and traverseM

Tags:

scala

scalaz

I am confused about the usage case about traverse, traverseU and traverseM, I searched it in the scalaz website, the simple code example:

 def sum(x: Int) = x + 1   List(1,2,3).traverseU(sum) 

it looks like it is similar to (map and aggregate):

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

I think it is more than that for traverseU, I just wonder what is the difference between those 3 method, it would be better I will have some sample code to show the difference

Many thanks in advance

like image 457
Xiaohe Dong Avatar asked Oct 28 '14 07:10

Xiaohe Dong


People also ask

What do you understand by traverse explain its types?

Traverse is a method in the field of surveying to establish control networks. It is also used in geodesy. Traverse networks involve placing survey stations along a line or path of travel, and then using the previously surveyed points as a base for observing the next point.

What is traversing and types of traversing?

There are two types of traverse surveying. They are: Closed traverse: When the lines form a circuit which ends at the starting point, it is known as a closed traverse. Open traverse: When the lines form a circuit ends elsewhere except starting point, it is said to be an open traverse.

What is the difference between open traverse and closed traverse?

Closed traverse: When the lines form a circuit which ends at the starting point, it is known as closed traverse. 2. Open traverse : When the lines form a circuit ends elsewhere except starting point, it is said to be an open traverse. The closed traverse is suitable for locating the boundaries of lakes, woods, etc.


1 Answers

sequence is used to gather together applicative effects. More concretely, it lets you "flip" F[G[A]] to G[F[A]], provided G is Applicative and F is Traversable. So we can use it to "pull together" a bunch of Applicative effects (note all Monads are 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 is equivalent to map then sequence, so you can use it when you have a function that returns an Applicative and you want to just get a single instance of your Applicative rather than a list of them:

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 is the same operation as traverse, just with the types expressed differently so that the compiler can infer them more easily.

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) is equivalent to traverse(f).map(_.join), where join is the scalaz name for flatten. It's useful as a kind of "lifting flatMap":

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)) 
like image 182
lmm Avatar answered Sep 24 '22 06:09

lmm