Scala 迭代时将thunk转换为序列
我有一个服务器API,它返回一个列表,并且一次返回25个条目。对于每个响应,我们都会得到一个项目列表和一个“令牌”,我们可以将其用于下面的服务器调用以返回下一个25,依此类推 请注意,我们使用的客户端库是用陈旧的易变Java编写的,并不适合Scala的所有功能组合模式 我正在寻找一种返回所有服务器项的延迟评估序列的方法,每当本地项列表用尽时,使用最新的令牌进行服务器调用。到目前为止,我得到的是:Scala 迭代时将thunk转换为序列,scala,lazy-sequences,Scala,Lazy Sequences,我有一个服务器API,它返回一个列表,并且一次返回25个条目。对于每个响应,我们都会得到一个项目列表和一个“令牌”,我们可以将其用于下面的服务器调用以返回下一个25,依此类推 请注意,我们使用的客户端库是用陈旧的易变Java编写的,并不适合Scala的所有功能组合模式 我正在寻找一种返回所有服务器项的延迟评估序列的方法,每当本地项列表用尽时,使用最新的令牌进行服务器调用。到目前为止,我得到的是: def fetchFromServer(uglyStateObject: StateObject):
def fetchFromServer(uglyStateObject: StateObject): Seq[Thing] = {
val results = server.call(uglyStateObject)
uglyStateObject.update(results.token())
results.asScala.toList ++ (if results.moreAvailable() then
fetchFromServer(uglyStateObject)
else
List())
}
但是,此函数不进行求值。我想要的是让++连接一个“严格序列”和一个“惰性序列”,其中一个thunk将用于从服务器检索下一组项目。实际上,我想要这样的东西:
results.asScala.toList ++ Seq.lazy(() => fetchFromServer(uglyStateObject))
除了我不知道用什么来代替Seq.lazy
到目前为止我所看到的事情:
- SeqView,但我看到一些评论说它不应该被使用,因为它一直在重新计算
- 流,但它们看起来好像抽象应该一次生成元素,而我想一次生成一堆元素
我应该用什么?我还建议你看看scalaz strem。下面是一个小例子,它可能是什么样子的
import scalaz.stream._
import scalaz.concurrent.Task
// Returns updated state + fetched data
def fetchFromServer(uglyStateObject: StateObject): (StateObject, Seq[Thing]) = ???
// Initial state
val init: StateObject = new StateObject
val p: Process[Task, Thing] = Process.repeatEval[Task, Seq[Thing]] {
var state = init
Task(fetchFromServer(state)) map {
case (s, seq) =>
state = s
seq
}
} flatMap Process.emitAll
事实上,在此期间,我已经找到了一个稍有不同的答案,我发现它更具可读性(实际上是使用流):
感谢大家我建议使用scalaz流
流程
。这表面上是面向单个元素视图的,但是有一个非常简单的API,您可以使用它一次发出一个块。
def fetchFromServer(uglyStateObject: StateObject): Stream[Thing] = {
val results = server.call(uglyStateObject)
uglyStateObject.update(results.token())
results.asScala.toStream #::: (if results.moreAvailable() then
fetchFromServer(uglyStateObject)
else
Stream.empty)
}