我对traverse,traverseU和traverseM的用例感到困惑,我在scalaz网站上搜索了它,简单的代码示例:
def sum(x: Int) = x + 1
List(1,2,3).traverseU(sum)
它看起来类似于(映射和聚合):
List(1,2,3).map(sum).reduceLeft(_ + _)
我认为它比traverseU还要多,我只是想知道这3种方法之间的区别是什么,所以我最好有一些示例代码来显示差异
提前谢谢了
最佳答案
sequence
用于收集应用效果。更具体地说,如果F[G[A]]
是G[F[A]]
和G
是Applicative
,它可以让您将F
“翻转”到Traversable
。因此,我们可以使用它来“组合”一堆Applicative
效果(请注意,所有Monad
都是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
的函数并且只想获取Applicative
的单个实例而不是它们的列表时,可以使用它: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
与traverse
是相同的操作,只是类型的表达不同,因此编译器可以更轻松地推断它们。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
是flatten
的标度名称。作为“提升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))
关于scala - 如何理解导线,导线U和导线M,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26602611/