Scalaz итерация, создайте Enumerator для BufferedReader

Как можно создать перечислитель для BufferedReader?

Я нашел довольно старую статью: http://apocalisp.wordpress.com/2010/10/17/scalaz-tutorial-enumeration-based-io-with-iteratees/ и похоже, что он не работает со Scalaz 6.0.4

Я пытаюсь создать Enumerator на основе примера отсюда: Идиоматическая конструкция для проверить заказана ли коллекция

 implicit val ListEnumerator = new Enumerator[List] {
   def apply[E, A](e: List[E], i: IterV[E, A]): IterV[E, A] = e match {
      case List() => i
      case x :: xs => i.fold(done = (_, _) => i,
                       cont = k => apply(xs, k(El(x))))
   }
 }

Но я не могу понять, как объединить монаду ввода-вывода с Enumerator


person Eugene Zhulenev    schedule 22.02.2012    source источник


Ответы (1)


Что не так со статьей Рунара? У меня работает следующая версия (Scalaz 6.0.4):

object FileIteratee {
  def enumReader[A](r: BufferedReader, it: IterV[String,  A]) : IO[IterV[String,  A]] = {
    def loop: IterV[String,  A] => IO[IterV[String,  A]] = {
      case i@Done(_, _) => i.pure[IO]
      case i@Cont(k) => for {
        s <- r.readLine.pure[IO]
        a <- if (s == null) i.pure[IO] else loop(k(El(s)))
      } yield a
    }
    loop(it)
  }

  def bufferFile(f: File) = new BufferedReader(new FileReader(f)).pure[IO]

  def closeReader(r: Reader) = r.close().pure[IO]

  def bracket[A,B,C](init: IO[A], fin: A => IO[B], body: A => IO[C]): IO[C] =
    for {
      a <- init
      c <- body(a)
      _ <- fin(a)
    } yield c

  def enumFile[A](f: File,  i: IterV[String,  A]) : IO[IterV[String, A]] =
    bracket(bufferFile(f),
            closeReader(_: BufferedReader),
            enumReader(_: BufferedReader,  i))
}
person lester    schedule 22.02.2012
comment
Спасибо, это работает! Но насколько я понимаю эволюцию скаляза, с версии 6 более удобный способ - предоставить Enumerator - person Eugene Zhulenev; 22.02.2012