如何使用Play迭代器创建一个无限枚举器

3

我希望能够创建一个枚举器,无限重复一系列元素,但我在想如何实现时遇到了问题。当我创建一个递归枚举器时,尝试引用它时似乎会导致堆栈溢出。例如,为了创建一个重复A、B、C、D、A、B、C、D、A、B、C、D、A...的枚举器,我希望使用以下内容:

scala> lazy val e1: Enumerator[String] = Enumerator("a","b","c","d") andThen e1
e1: play.api.libs.iteratee.Enumerator[String] = <lazy>

但是,当我试图使用它时,会出现堆栈溢出的问题:

scala> e1 through Enumeratee.take(1) apply Iteratee.foreach(println(_)
java.lang.StackOverflowError
    at .e1$lzycompute(<console>:11)
    at .e1(<console>:11)
    at .e1$lzycompute(<console>:11)
    at .e1(<console>:11)
    at .e1$lzycompute(<console>:11)
    at .e1(<console>:11)

你可能想看一下这个编程问题,特别是关于流和continually的答案,看看是否可以将其应用到枚举器中:https://dev59.com/XnA75IYBdhLWcg3wg5Vh - cmbaxter
1
也许这太无聊了,但是Enumerator.repeat(()).flatMap(_ => elems)怎么样?其中elems是您的元素枚举器。 - Travis Brown
1个回答

3

哎呀,我自问自答

感谢@travis和@cmbaxter向我指出了正确的方向。我一直在查看旧的源代码和api文档,没有看到像repeat这样的新方法。对我来说,解决问题的关键是unfold:

scala> val s: Stream[String] = "A" #:: "B" #:: "C" #:: "D" #:: s
s: Stream[String] = Stream(A, ?)

scala> Enumerator.unfold(s)(s => Some(s.tail, s.head)) through Enumeratee.take(10) apply Iteratee.foreach(println(_))
res3: scala.concurrent.Future[play.api.libs.iteratee.Iteratee[String,Unit]] = scala.concurrent.impl.Promise$DefaultPromise@55d3e052

scala> A
B
C
D
A
B
C
D
A
B

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接