我想编写一个枚举,只需将一个Input.El推入iteratee,然后返回剩余的iteratee。我把它称为prepend,因为它只是通过为它添加一个值来改变流。 这是我的尝试:
object Enumeratees {
def prepend[T](toPrepend: T) = new Enumeratee[T, T] {
def applyOn[A](inner: Iteratee[T, A]): Iteratee[T, Iteratee[T, A]] = {
val prepended = Iteratee.flatten(inner.feed(Input.El(toPrepend)))
Done(prepended, Input.Empty)
}
}
}
我现在通过
打电话Enumerator(1,2,3,4) |>> (Enumeratees.prepend(0) &>> Iteratee.foreach[Int]{i=>println(i)})
它只打印应该预先添加的0。枚举器中的其他值将被忽略。如果我也覆盖&>枚举的方法(变换方法),我可以使它工作:
def prepend[T](toPrepend: T) = new Enumeratee[T, T] {
def applyOn[A](inner: Iteratee[T, A]): Iteratee[T, Iteratee[T, A]] = {
val prepended = Iteratee.flatten(inner.feed(Input.El(toPrepend)))
Done(prepended, Input.Empty)
}
override def transform[A](inner: Iteratee[T,A]): Iteratee[T,A] =
Iteratee.flatten(inner.feed(Input.El(toPrepend)))
}
但这不是一种非常干净的方式,因为applyOn方法仍然无效。 我想我错误地认识了applyOn方法的含义。在我看来,它应该返回一个返回原始iteratee的iteratee,然后在原始的iteratee上继续输入。
上面的转换方法应该解释一下,我想从我的枚举中得到什么样的行为。如何通过覆盖applyOn而不是transform?
来实现此行为答案 0 :(得分:7)
您可以编辑前缀Enumeratee,如下所示:
object Enumeratees {
def prepend[T](toPrepend: T) = new Enumeratee[T, T] {
def applyOn[A](inner: Iteratee[T, A]): Iteratee[T, Iteratee[T, A]] = {
val prepended = Iteratee.flatten(inner.feed(Input.El(toPrepend)))
Enumeratee.passAlong[T](prepended)
}
}
}
或者在将Enumeratee和Enumerator应用到它之后,你得到了原始的Iteratee,类似于Scala: Getting original iteratee after applying enumeratee (example from play documentation doesn't compile)
当外部完成时, &>>
将结束内部迭代。这是能够获得Iteratee[EOuter,AInner]
的唯一方法,因为Enumeratee主要是关于适应。
答案 1 :(得分:0)
怎么样?
Enumerator(1,2,3,4) |>>
Iteratee.flatten( Enumerator(0) |>> Iteratee.foreach[Int]{i=>println(i)} )
或
Enumerator(1,2,3,4) |>> (Enumeratees.prepend2(0) &> Iteratee.foreach[Int]{i=>println(i)})