【发布时间】:2013-06-25 00:43:40
【问题描述】:
我见过的 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]
}
我的问题很简单:为什么正是需要 Empty 输入案例?
迭代模式定义了值流的生产者和消费者之间的关系。直观地说,如果任何输入为空,“运行”迭代器的生产者应该简单地折叠该空项,并且在非空输入可用之前不调用迭代器。
我注意到基于 pull 的 iteratees 类比,更熟悉的迭代器,不定义空案例,尽管元素可能已被过滤掉“内部”迭代器。
trait Iterator[E] {
next: E // like El
hasNext: Boolean //like EOF
}
虽然上述所有博客都提到需要空输入,但他们没有明确讨论为什么不能完全消除它。我注意到显示的示例迭代器将空输入视为无操作。
我真的很想要一个带有代码的示例,说明一个看似合理的“现实世界”问题,需要 Empty 输入消息来解决。
【问题讨论】:
-
对 monad / applicative 法则的呼吁是否不够“真实世界”?试着想想如果没有
Empty,你将如何为Iteratee[E, _]定义pure。 -
@TravisBrown,
pure(a: A) = Done(a)?我会从那里开始,看看它是否有效。 -
@huynhjl:
Done的构造函数有两个参数,如果看起来有一个只有一个的重载版本,那是因为第二个默认为Empty。 -
@TravisBrown,但如果 iteratee 库设计为使用只有一个参数且没有
Empty作为Input构造函数之一的Done,我的感觉是您仍然可以定义pure、map 和 flatMap 并让Iteratee[E, _]成为一个单子。因此,这不是输入空的动机。