【问题标题】:Why does foldRight of a list return a future and not a new list?为什么列表的 foldRight 返回未来而不是新列表?
【发布时间】:2014-11-15 10:58:26
【问题描述】:

鉴于此代码将 List[Future[T]] 转换为 Future[List[T]]

def all[T](fs: List[Future[T]]): Future[List[T]] = {

  val p = Promise[List[T]]() //create an empty promise which will contain the result (i.e. the future)
  p.success(Nil) //initialise: the result of the promise is a Future of an empty list
  fs.foldRight(p.future) { //accumulator is the future of the promise
    (oneFutueFromTheList, accFutureOfAList) =>
      for (
        actualValueOfFuture <- oneFutueFromTheList; //unpack the item in the future
        theList <- accFutureOfAList //unpack the list from the future
      ) yield actualValueOfFuture :: theList //append the item to the list
  }

}

for 推导的产出是一个 List[T]。

为什么 foldRight 返回 Future[List[T]](而不是 List[T])?是不是因为 foldRight 的累加器是 Future[List[T]] 并且 foldRight 足够“聪明”,知道将收益率的结果 List[T] 放入 Future[List[T]] ?

代码来源:https://class.coursera.org/reactive-001响应式编程原理

【问题讨论】:

    标签: scala promise future


    【解决方案1】:

    因为p.futureFuture[List[T]]foldRight 的签名是foldRight[B](z: B)(op: (A, B) ⇒ B): B

    在这种情况下,zp.future,所以 BFuture[List[T]]

    【讨论】:

    • 那么累加器(z:B)的类型决定了结果的类型,而Scala在后台确保列表(来自for理解/yield)成为未来的值?
    【解决方案2】:

    for comprehension 只是 flatMaps 和 maps 的合成糖,所以这个循环实际上是:

    oneFutueFromTheList.flatMap(actualValueOfFuture =>
      accFutureOfAList.map(theList =>
        actualValueOfFuture :: theList))
    

    foldRight 的签名是:foldRight[B](z: B)(op: (A, B) =&gt; B): B
    foldRight 将 z 作为初始化值,并为每个项目运行 op 函数。 op 函数应该返回 Z 类型的值,在这种情况下是 List[T]。 op 函数现在再次运行,这次 Z 是最后一个 op 返回值。这对集合中的所有项目继续进行。
    foldRight 的返回值是 op 函数返回的最后一个 Z。

    【讨论】:

    • 因此地图采用 List[T] (actualValueOfFutre::theList) 并将其“打包”到 Future[List[T]]。
    猜你喜欢
    • 1970-01-01
    • 2011-11-10
    • 2016-09-18
    • 1970-01-01
    • 2019-12-20
    • 2019-11-23
    相关资源
    最近更新 更多