How to understand traverse, traverseU and traverseM

前端 未结 1 1474
闹比i
闹比i 2021-01-30 02:38

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条回答
  • 2021-01-30 03:05

    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))
    
    0 讨论(0)
提交回复
热议问题