2016-08-24 5 views
3

의 내용에 따라 파일을 열 :파이프 : 나는이 코드가 다른

import Pipes 
import Pipes.Safe 
import qualified Pipes.Prelude as P 
import qualified Pipes.Safe.Prelude as P 
import System.IO 

import Data.Text as T 
import Data.Text.IO as TIO 
import qualified Pipes.Prelude.Text as T 

someFunc :: IO() 
someFunc = runSafeT $ 
    P.withFile file1 ReadMode $ \file1Handle -> do 
    file2 <- liftIO $ TIO.hGetLine file1Handle 
    runEffect $ 
     for (P.zip (T.fromHandleLn file1Handle) 
       (T.readFileLn $ T.unpack file2)) 
      (\(l1,l2) -> do yield l2 
          yield l1) 
     >-> T.stdoutLn 

을하지만 꽤 해키 것, 그리고 내가에서, 파이프 내에서 두번째 파일을 열 수 있도록하고 싶습니다 무엇 첫 번째 파일의 첫 줄을 읽었습니다. 아이디어가 있으십니까?

+0

나는 아마도 당신이 얻을 수있는 가장 깨끗한 코드 일 것이라고 생각합니다. 여기에서 답을 얻지 못하면 [pipe mailing list] (https://groups.google.com/forum/#!forum/haskell-pipes)를 시도한 다음 여기에 답변을 게시하십시오. – ErikR

답변

2

나는 Pipes와 함께 Data.Text.IO을 혼합하지 않고이 작업을 수행하는 여러 가지 방법이 있다고 생각합니다. 그것은 기본적으로 zip입니다.

someFunc_ = runSafeT $ runEffect $ do 
    e <- next (T.readFileLn file1) 
    case e of 
    Left r    -> return r 
    Right (file2, rest) -> do 
     let other = T.readFileLn (T.unpack file2) 
      amalgam = for (P.zip rest other) $ \(l1,l2) -> do 
      yield l2 
      yield l1 
     runEffect $ amalgam >-> T.stdoutLn 

내가 생각에 시도 접근 방법 : 첫 번째 파일의 첫 번째 줄을 찾는 자연적인 방법이 경우에, 당신 라인의 나머지와 짝을 첫 번째 라인을 제공하는 단지 next을 사용하는 것입니다 더 많은 '내부 파이프 라인'이 결국 가치가있는 것보다 더 복잡해질 것입니다. 특히 file1이 비어있는 경우를 처리해야합니다. next은 기본적으로 파이프 Producer에 일치 패턴을 적용하는 데 사용되므로 기본적인 파이프 작업입니다.

그래서, 부분 부분이 제대로 스트림 것을 제외하고이

someFunc = do 
    ls <- fmap T.lines TIO.readFile file1 
    case ls of 
     []   -> return() 
     file2:rest -> do 
     ls' <- fmap T.lines (TIO.readFile file1) 
     forM_ (zip ls ls') $ \(t1,t2) -> do 
      TIO.putStrLn t1 
      TIO.putStrLn t2 

처럼 기본적으로 일반 텍스트 프로그램과 동일합니다.

+0

고마워요! 실제로 '다음'은 여기에 빠진 요소였습니다. –