gpt4 book ai didi

scala - 使用 Scala 延续实现 yield ( yield 返回)

转载 作者:行者123 更新时间:2023-12-03 10:12:31 26 4
gpt4 key购买 nike

如何实现 C# yield return使用 Scala 延续?我希望能够编写 Scala Iterator s 风格相同。在 this Scala news post 的评论中有刺伤,但它不起作用(尝试使用 Scala 2.8.0 beta)。答案在 related question建议这是可能的,但是虽然我已经玩了一段时间的分隔延续,但我似乎无法完全理解如何做到这一点。

最佳答案

在我们介绍延续之前,我们需要构建一些基础设施。
下面是一个 trampoline运行于 Iteration对象。
迭代是一种计算,可以 Yield一个新值或者它可以是 Done .

sealed trait Iteration[+R]
case class Yield[+R](result: R, next: () => Iteration[R]) extends Iteration[R]
case object Done extends Iteration[Nothing]

def trampoline[R](body: => Iteration[R]): Iterator[R] = {
def loop(thunk: () => Iteration[R]): Stream[R] = {
thunk.apply match {
case Yield(result, next) => Stream.cons(result, loop(next))
case Done => Stream.empty
}
}
loop(() => body).iterator
}

蹦床使用内部循环,将 Iteration 的序列轮流对象变成 Stream .
然后我们得到一个 Iterator调用 iterator在生成的流对象上。
通过使用 Stream我们的评价是懒惰的;在需要之前,我们不会评估我们的下一次迭代。

蹦床可用于直接构建迭代器。
val itr1 = trampoline {
Yield(1, () => Yield(2, () => Yield(3, () => Done)))
}

for (i <- itr1) { println(i) }

写起来非常糟糕,所以让我们使用分隔的延续来创建我们的 Iteration对象自动。

我们使用 shiftreset运算符将计算分解为 Iteration
然后使用 trampolineIteration s 变成 Iterator .
import scala.continuations._
import scala.continuations.ControlContext.{shift,reset}

def iterator[R](body: => Unit @cps[Iteration[R],Iteration[R]]): Iterator[R] =
trampoline {
reset[Iteration[R],Iteration[R]] { body ; Done }
}

def yld[R](result: R): Unit @cps[Iteration[R],Iteration[R]] =
shift((k: Unit => Iteration[R]) => Yield(result, () => k(())))

现在我们可以重写我们的例子。
val itr2 = iterator[Int] {
yld(1)
yld(2)
yld(3)
}

for (i <- itr2) { println(i) }

好多了!

现在这里有一个来自 C# reference page 的例子为 yield这显示了一些更高级的用法。
这些类型可能有点难以习惯,但一切正常。
def power(number: Int, exponent: Int): Iterator[Int] = iterator[Int] {
def loop(result: Int, counter: Int): Unit @cps[Iteration[Int],Iteration[Int]] = {
if (counter < exponent) {
yld(result)
loop(result * number, counter + 1)
}
}
loop(number, 0)
}

for (i <- power(2, 8)) { println(i) }

关于scala - 使用 Scala 延续实现 yield ( yield 返回),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2201882/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com