另一个 scala Futures 组合益智游戏
Another scala Futures composition puzzler
我正在将代码从同步样式迁移到异步样式。问题相当简单:调用一系列函数,然后停止第一个函数以 return 一个非错误结果(returning 该值,否则是最后一个计算值)。我开始于:
def find(fs: Seq[Function0[Int]], result: Int = -1): Int = {
if (fs.isEmpty) result
else {
val res = fs.head()
if (res != 0) res
else find(fs.tail, res)
}
}
但是,如果函数变为异步(即 return Future[Int]),我将无法获得正确的调用。例如,
def ffind(ffs: Seq[Function0[Future[Int]]], result: Future[Int] = Future { -1 }): Future[Int] = {
if (ffs.isEmpty) result
else ffind(ffs.tail, ffs.head())
}
效果很好,但它会评估所有函数,而不管 return 值如何。但是像:
def findBad(ffs: Seq[Function0[Future[Int]]], result: Future[Int] = Future { -1 }): Future[Int] = {
if (ffs.isEmpty) result
else {
ffs.head() map { res =>
if (res != 0) res
else findBad(ffs.tail, Future(res))
}
}
}
不进行类型检查。有什么建议么?我们可以假设函数的每次调用都是昂贵的,因此 none 应该被调用两次,也不应在序列中的第一个 'successful' 调用之后调用。 TIA
这就是它不进行类型检查的原因:findBad
returns a Future[Int]
,但是将 res
映射到 findBad
的调用会导致在Future[Future[Int]]
。您需要将 map
更改为 flatMap
。请注意,现在您还需要将第一个条件(如果 res != 0)中的 res
包装到 Future
中,以便两个分支 return 和 Future
。这是代码:
ffs.head() flatMap { res =>
if (res != 0) Future.succesful(res)
else findBad(ffs.tail, Future(res))
}
顺便说一句,如果你想 运行 它们全部 return 以先完成的为准,忽略所有其余部分,那么问题就有点不同了(见 ),但你说每个函数调用都很昂贵,所以我怀疑这就是你想要做的。
我正在将代码从同步样式迁移到异步样式。问题相当简单:调用一系列函数,然后停止第一个函数以 return 一个非错误结果(returning 该值,否则是最后一个计算值)。我开始于:
def find(fs: Seq[Function0[Int]], result: Int = -1): Int = {
if (fs.isEmpty) result
else {
val res = fs.head()
if (res != 0) res
else find(fs.tail, res)
}
}
但是,如果函数变为异步(即 return Future[Int]),我将无法获得正确的调用。例如,
def ffind(ffs: Seq[Function0[Future[Int]]], result: Future[Int] = Future { -1 }): Future[Int] = {
if (ffs.isEmpty) result
else ffind(ffs.tail, ffs.head())
}
效果很好,但它会评估所有函数,而不管 return 值如何。但是像:
def findBad(ffs: Seq[Function0[Future[Int]]], result: Future[Int] = Future { -1 }): Future[Int] = {
if (ffs.isEmpty) result
else {
ffs.head() map { res =>
if (res != 0) res
else findBad(ffs.tail, Future(res))
}
}
}
不进行类型检查。有什么建议么?我们可以假设函数的每次调用都是昂贵的,因此 none 应该被调用两次,也不应在序列中的第一个 'successful' 调用之后调用。 TIA
这就是它不进行类型检查的原因:findBad
returns a Future[Int]
,但是将 res
映射到 findBad
的调用会导致在Future[Future[Int]]
。您需要将 map
更改为 flatMap
。请注意,现在您还需要将第一个条件(如果 res != 0)中的 res
包装到 Future
中,以便两个分支 return 和 Future
。这是代码:
ffs.head() flatMap { res =>
if (res != 0) Future.succesful(res)
else findBad(ffs.tail, Future(res))
}
顺便说一句,如果你想 运行 它们全部 return 以先完成的为准,忽略所有其余部分,那么问题就有点不同了(见