h-oikawa
9/18/2017 - 5:17 AM

From http://d.hatena.ne.jp/shomah4a/20110105/1294217529

import scala.actors


object StopIteration

class Yielder[T](postto: actors.Actor)
{
  def ! (v: T)
  {
    postto ! v
  }
}

class Generator[T](genfunc: (Yielder[T])=>Unit) extends Iterator[T]
{
  private val self = actors.Actor.self

  private var finished = false

  private val actor = actors.Actor.actor
  {
    val msger = new Yielder[T](this.self)

    genfunc(msger)

    this.self ! StopIteration
  }

  private var nextValue: Option[T] = None

  def iterate()
  {
    this.nextValue = this.self.receive
    {
      case StopIteration =>
        {
          this.finished = true
          None
        }
      case v: T => Some(v)
      case x => None
    }
  }

  def hasNext() = 
    {
      if (this.finished)
        {
          false
        }
      else
        {
          this.iterate
          this.nextValue != None
        }
    }

  def next() = this.nextValue.get

}

object Generator
{
  def apply[T](func: Yielder[T]=>Unit) = new Generator[T](func)
}