Scala 迭代时将thunk转换为序列

Scala 迭代时将thunk转换为序列,scala,lazy-sequences,Scala,Lazy Sequences,我有一个服务器API,它返回一个列表,并且一次返回25个条目。对于每个响应,我们都会得到一个项目列表和一个“令牌”,我们可以将其用于下面的服务器调用以返回下一个25,依此类推 请注意,我们使用的客户端库是用陈旧的易变Java编写的,并不适合Scala的所有功能组合模式 我正在寻找一种返回所有服务器项的延迟评估序列的方法,每当本地项列表用尽时,使用最新的令牌进行服务器调用。到目前为止,我得到的是: def fetchFromServer(uglyStateObject: StateObject):

我有一个服务器API,它返回一个列表,并且一次返回25个条目。对于每个响应,我们都会得到一个项目列表和一个“令牌”,我们可以将其用于下面的服务器调用以返回下一个25,依此类推

请注意,我们使用的客户端库是用陈旧的易变Java编写的,并不适合Scala的所有功能组合模式

我正在寻找一种返回所有服务器项的延迟评估序列的方法,每当本地项列表用尽时,使用最新的令牌进行服务器调用。到目前为止,我得到的是:

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)
}