2013-08-18 3 views
2

scala와 함께 scalaz 6.0을 사용하고 있습니다. 입력 스트림에서 읽기 위해 iteratees를 사용하고 있습니다.표준 입출력에서 입력 반복

내가 가진 simple.txt라는 간단한 파일이 있습니다.



테스트입니다

내 iteratee는 라인

def printLines: IterV[String, IO[Unit]] = { 
    def step(currentIO: IO[Unit])(input: Input[String]): IterV[String, IO[Unit]] = 
    input match { 
     case El(x) => Cont(
      step(
       currentIO.flatMap(_ => putStrLn(x)) 
     ) 
    ) 
     case IterV.Empty() => Cont(step(currentIO)) 
     case EOF() => Done(currentIO, EOF[String]) 
    } 
    Cont(step(io())) 
} 

나는 enumeratorM를 사용

를 인쇄하는 IO 모나드를 구축 할 것입니다

getFileLines(new File(".../simple.txt"))(printLines).flatMap(_.run).unsafePerformIO 

올바른 출력을 검색합니다.

나는 나는 단지 "이"다시 콘솔 얻을

getLines(printLines).flatMap(_.run).unsafePerformIO 

를 사용하려고하면. getLines는 표준 입력 스트림을 사용합니다. 디버그 문을 iteratee에 추가했고 getLines가 첫 번째 줄 다음에 EOF()를 보내는 것으로 보이며 해결할 수 없었습니다.

답변

2

이것은 getReaderLines의 정의 버그입니다.

/** Enumerate the lines from a BufferedReader */ 
def getReaderLines(r: => BufferedReader): EnumeratorM[IO, String] = 
    new EnumeratorM[IO, String] { 
    lazy val reader = r 

    def apply[A](it: IterV[String, A]) = { 
     def loop(i: IterV[String, A]): IO[IterV[String, A]] = i.fold(
     done = (_,_) => io { i }, 
     cont = k => for { 
      s <- rReadLn(reader) 
      a <- s.map(l => loop(k(El(l)))).getOrElse(io(i)) 
     } yield a 
    ) 
     loop(it) 
    } 
    } 

문제는 rgetLines가 정의하는 방식을 제공한다는 의미로 이름 매개 변수라는 것이다, 현재 버전 : 하나의 작품으로

/** Enumerate the lines from a BufferedReader */ 
def getReaderLines(r: => BufferedReader): EnumeratorM[IO, String] = 
    new EnumeratorM[IO, String] { 
    def apply[A](it: IterV[String, A]) = { 
     def loop(i: IterV[String, A]): IO[IterV[String, A]] = i.fold(
     done = (_,_) => io { i }, 
     cont = k => for { 
      s <- rReadLn(r) 
      a <- s.map(l => loop(k(El(l)))).getOrElse(io(i)) 
     } yield a 
    ) 
     loop(it) 
    } 
    } 

: 현재 버전 비교 모든 루프에 표준 입력을 래핑하는 새로운 리더를 만듭니다.

val getLines: EnumeratorM[IO, String] = { 
    val r = new BufferedReader(new InputStreamReader(System.in)) 
    getReaderLines(r) 
} 

이까지

라이브러리에 고정됩니다 (그리고 내가 문 밖으로 6.0.5을 얻을 수있는 러시 많이있을거야 의심), 간단한 수정은 자신의 getLines을 작성하는 것입니다 이것은 예상대로 작동합니다.