Question

I'm reading the source code of Iteratee.scala: https://github.com/playframework/Play20/blob/master/framework/src/iteratees/src/main/scala/play/api/libs/iteratee/Iteratee.scala

Specifically the convenience method for constructing the "fold" iteratee.

def fold[E, A](state: A)(f: (A, E) => A): Iteratee[E, A] = {
  def step(s: A)(i: Input[E]): Iteratee[E, A] = i match {

    case Input.EOF => Done(s, Input.EOF)
    case Input.Empty => Cont[E, A](i => step(s)(i))
    case Input.El(e) => { val s1 = f(s, e); Cont[E, A](i => step(s1)(i)) }
  }
  (Cont[E, A](i => step(state)(i)))
}  

On each of the case statements, we are calling Done or Cont constructors. But where are these constructors defined? I infer that these must be implementors of the Iteratee trait but I couldn't find them by doing ctrl+F for "extends Iteratee."

Was it helpful?

Solution

See docementation or source:

object Done {
/**
* Create an [[play.api.libs.iteratee.Iteratee]] in the “done” state.
* @param a Result
* @param e Remaining unused input
*/
  def apply[E, A](a: A, e: Input[E] = Input.Empty): Iteratee[E, A] = new Iteratee[E, A] {
    def fold[B](folder: Step[E, A] => Future[B]): Future[B] = folder(Step.Done(a, e))
  }
}

It's not a constructor. Done(s, Input.EOF) means Done.apply(s, Input.EOF). Same with Cont.

OTHER TIPS

Done doesn't need to directly extend Iteratee. It could extend another class or trait which then extends Iteratee. You could search for class Cont and then follow the inheritance relationship from there.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top