管道:根据另一个文件的内容打开一个文件
Pipes: open a file according to content of another
我有这个代码:
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
但这看起来很老套,我希望能够从管道中打开第二个文件,从我在第一个文件的第一行中读到的内容。
有什么想法吗?
我认为有很多方法可以做到这一点,而无需将 Data.Text.IO
与 Pipes
混在一起。正如您所说,它基本上是一个 zip
。找出第一个文件的第一行的自然方法就是使用 next
,在这种情况下,它会为您提供与其余行配对的第一行:
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
我认为尝试做更多事情的方法 'inside a pipeline' 最终会变得比它值得的更复杂。特别是,您必须处理 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
除非它正确地流式传输。
我有这个代码:
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
但这看起来很老套,我希望能够从管道中打开第二个文件,从我在第一个文件的第一行中读到的内容。 有什么想法吗?
我认为有很多方法可以做到这一点,而无需将 Data.Text.IO
与 Pipes
混在一起。正如您所说,它基本上是一个 zip
。找出第一个文件的第一行的自然方法就是使用 next
,在这种情况下,它会为您提供与其余行配对的第一行:
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
我认为尝试做更多事情的方法 'inside a pipeline' 最终会变得比它值得的更复杂。特别是,您必须处理 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
除非它正确地流式传输。