为什么Scala Iteratees中需要Empty输入案例?

Ben*_*son 9 scala iterate

我见过的Scala中Iteratee模式的3个描述包括3个输入案例.例如,詹姆斯:

sealed trait Input[+E]
object Input {
  case object EOF extends Input[Nothing]
  case object Empty extends Input[Nothing]
  case class El[+E](e: E) extends Input[E]
}
Run Code Online (Sandbox Code Playgroud)

更多细节见James,Runar,Josh的博客.

我的问题很简单:为什么恰恰是空输入情况下需要的?

iteratee模式定义了生产者和价值流的消费者之间的关系.直观地说,似乎如果任何输入为空,那么"运行"iteratee的生产者应该简单地将该空项目折叠掉,并且在非空输入可用之前不调用iteratee.

我注意到迭代器的基于拉的模拟,更常见的迭代器,没有定义一个空的情况,尽管元素可能已经在迭代器"内部"被过滤掉了.

trait Iterator[E] {
    next: E        // like El
    hasNext: Boolean  //like EOF
}
Run Code Online (Sandbox Code Playgroud)

虽然上述所有博客都提到需要传递空输入,但他们没有明确讨论为什么它不能完全消除.我注意到显示的示例迭代器将空输入视为无操作.

我真的很喜欢一个带有代码的例子,它有一个看似合理的"真实世界"问题,需要空输入消息来解决.

huy*_*hjl 3

假设您连接了一个枚举器,该枚举器将一些元素提供给peek迭代器,该迭代器查看第一个元素并返回它但不消耗它,使其可能由将由 . 组成的另一个迭代器使用peek。然后您需要提供一种机制来peek放回该元素。据我所知,Play 和 Scalaz iteratee 都认为,done iteratee 只为此目的而采用一个参数。所以你可以用伪代码做类似的事情done(Some(result), El(result)):请参阅peek 的实现

现在,如果您实现类似head实际消耗元素的东西,那么感觉一种方法就是返回done(Some(result), emptyInput)以指示输入已消耗。

另请参阅playframework 源代码中的此注释,显示 Done(_, _) 的第二个参数用于未使用的输入并初始化为空默认值。所以空并不是很少使用的东西,很难找到现实世界的例子。这对于 iteratee 的实现来说确实是关键。事实上,看看哪些 iteratee 框架没有空以及它们如何实现 peek 和 head 可能会很有趣。