実際にファイルを読み込めるようにしました。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type EnumeratorM[E, M[_], A] = IterV[E, A] => M[IterV[E, A]] | |
def enumReader[A](r: BufferedReader): EnumeratorM[String, IO, A] = { iter => | |
def loop: EnumeratorM[String, IO, A] = { | |
case i @ Done(_, _) => (i: IterV[String, A]).pure[IO] | |
case i @ Cont(k) => for { | |
o <- rReadLn(r) | |
i <- o match { | |
case None => i.pure[IO] | |
case Some(s) => s.pure[IO] >>= loop.compose(k.compose(El(_))) | |
} | |
} yield i | |
} | |
loop(iter) | |
} | |
def enumFile[A](f: File): EnumeratorM[String, IO, A] = i => bufferFile(f).bracket(closeReader)(enumReader[A](_)(i)) |
EnumeratorMはIterVをモナドで包むための型です。
enumReaderはブログの例とは違いますが、一字ずつ読み込むのではなく、BufferReaderを用いて一行づつ読み込むようにしています。
<<<はScalazで定義されており、composeと同じです。
enumと同様に、Doneになるまで処理を繰り返します。
enumFileはファイルをenumReaderに渡す。
bracketにより、closeReaderが確実に行われることが保証されています。
実行例
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val file = new File("src/main/resources/test.txt") | |
file.exists assert_=== true | |
def g[A](i: IterV[String, A]) = run(enumFile(file)(i).unsafePerformIO) | |
g(length) assert_=== Some(1) | |
g(peek[String] >|> head[String]) assert_=== Some(Some("hello")) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
hello |
現在、scalaz.effectsにあるIterateeな入出力関数はこれらと、標準入力からの読み込みだけです。