2012-02-22 53 views
3

如何爲BufferedReader創建枚舉器?Scalaz迭代器,爲BufferedReader創建枚舉器

我發現相當老的文章:http://apocalisp.wordpress.com/2010/10/17/scalaz-tutorial-enumeration-based-io-with-iteratees/,它看起來像它不與Scalaz 6.0.4工作

我嘗試基於例如從這裏創建枚舉:Idiomatic construction to check whether a collection is ordered

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)))) 
    } 
} 

但我無法理解如何將IO monad與枚舉器相結合

回答

3

Rúnar的文章有什麼問題?以下版本正在爲我工​​作(斯卡拉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 [email protected](_, _) => i.pure[IO] 
     case [email protected](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)) 
} 
+0

謝謝,它的工作!但據我所知,scalaz的演變,從6版本更方便的方式是提供枚舉器 – 2012-02-22 15:31:24