如何理解traverse、traverseU和traverseM [英] How to understand traverse, traverseU and traverseM

查看:38
本文介绍了如何理解traverse、traverseU和traverseM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对traverse、traverseU和traverseM的使用案例很困惑,我在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(_ + _)

我认为对于 traverseU 来说不止这些,我只是想知道这 3 种方法之间有什么区别,最好我提供一些示例代码来显示区别

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

非常感谢

推荐答案

sequence 用于聚集应用效果.更具体地说,它可以让您翻转"F[G[A]]G[F[A]],前提是 GApplicativeFTraversable.所以我们可以用它来聚合"一堆 Applicative 效果(注意所有 Monad 都是 Applicative):

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 等价于 map 然后是 sequence,所以当你有一个返回 Applicative<的函数时你可以使用它/code> 并且您只想获得 Applicative 的单个实例而不是它们的列表:

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]]

traverseUtraverse 的操作相同,只是类型表达不同,以便编译器更容易推断.

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) 等价于 traverse(f).map(_.join),其中 join扁平化.它作为一种提升 flatMap"很有用:

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))

这篇关于如何理解traverse、traverseU和traverseM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆