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

时间:2013-06-25 00:43:41

标签: 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]
}

更多详情请参阅JamesRunarJosh的博客。

我的问题很简单:为什么正好是需要的空输入案例?

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

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

trait Iterator[E] {
    next: E        // like El
    hasNext: Boolean  //like EOF
}

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

我真的很喜欢一个代码,一个看似合理的“真实世界”问题的例子,需要空输入消息才能解决。

2 个答案:

答案 0 :(得分:3)

假设您连接了一个枚举器,该枚举器将一些元素提供给查看第一个元素的peek iteratee并返回它但不消耗它,让它可能被另一个将被组成的iteratee使用peek。然后,您需要提供peek放回元素的机制。从我从Play和Scalaz iteratee可以看出, done iteratee仅为此目的而采用了一个参数。所以你可以在伪代码中做一些事情:done(Some(result), El(result))。请参阅this implementation of peek

现在,如果你实现类似head的实际消耗元素的东西,那么感觉就像回到done(Some(result), emptyInput)以指示输入被消耗一样。

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

答案 1 :(得分:2)

James Roper提供了有用的回复here,包括我觉得有趣的这个片段:

  

我想另一种可以实现的方法是选择[输入]   作为完成的剩余输入。这将使实施   迭代更简单,因为他们不需要处理空。