“无形状”功能概述包含使用everywhere
函数recursively transform a tree, by applying a given function的示例:
object inc extends ->((i: Int) => i + 1)
everywhere(inc)(tree)
我的问题:如果我们有asyncInc
函数返回scala.concurrent.Future[Int]
,那么如何实现asyncEverywhere
函数,该函数将返回Future
修改后的Tree
{1}}?
用法如下:
object asyncInc extends ->((i: Int) => Future { i + 1 } )
val treeFuture: Future[Tree[Int]] = asyncEverywhere(asyncInc)(tree)
答案 0 :(得分:1)
如果我要编写asyncEverywhere
方法,我会调用everywhere
两次,并传递不同的函数。
第一个是副作用身份功能。
作为副作用,它将启动适当的Future
并将其添加到可变列表中。
当遍历的第一遍完成时,我得到Future
s的列表。
现在,我可以致电Future.sequence
将其转换为Future
个列表。我在此map
上调用Future
来转换以下列表
办法:
- 我在everywhere
上拨打Tree
,这次是另一个功能。第二个函数只是将其后续结果从列表中拉出,从左开始(请记住,这将是一个可变列表)。由于列表的大小与处理的元素数相匹配。
这可能是这样的:
import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
import scala.language.postfixOps
def asyncEverywhere[T](asyncF: T => Future[T], tree: Tree[T])
(implicit ec: ExecutionContext) = {
val queue = scala.collection.mutable.Queue[Future[T]]()
object enqueueFutures extends ->({ (i: T) =>
queue.enqueue(asyncF(i))
i
})
everywhere(enqueueFutures)(tree)
Future.sequence(queue) map { q =>
object dispenseResults extends (T -> T)(_ => q.dequeue())
everywhere(dispenseResults)(tree)
}
}
println(Await.result(
asyncEverywhere(
(i: Int) => Future { i + 1 },
tree),
1 minute))