What is best here might of course depend on *where you are getting the filenames from*, and *what you are going to do with the pairs of first lines*. I was wondering if some of the trouble you felt was the constriction you're under with `System.IO.withfile`. Its complexity is sort of replicated by the type of bgamari's `doThings`:
doThings :: FilePath -> FilePath -> (Producer (String,String) IO () -> IO ()) -> IO ()
doThings keyPath secretPath f = do
If you use the `withFile` from Pipes.Safe, you have a few more options, but are put under a MonadSafe constraint. In fact the `readFile` from `Pipes.Safe.Prelude` has the same simple line-by-line behavior that `Pipes.Prelude.fromHandle` has, so you could as well write
buildAuthP :: MonadSafe m => FilePath -> FilePath -> Producer (String, String) m ()
buildAuthP keypath secretpath =
P.zip (S.readFile keypath >-> P.take 1)
(S.readFile secretpath >-> P.take 1)
in the confident security that files will be properly closed. If you keep in mind the ways of managing the constraint that `m` must be a MonadSafe, this gives you a little more freedom of operation. So here I reuse `buildAuthP` repeatedly to produce pairs of strings . It is just a question of finessing the SafeT machinery appropriately.
import Pipes
import Pipes.Safe
import qualified Pipes.Safe.Prelude as S
import qualified Pipes.Prelude as P
import System.IO
import Control.Monad.IO.Class
main = runEffect effect1 where
effect1 = for filePairs (\(a,b) -> hoist runSafeT (buildAuthP a b) >-> P.print)
effect2 = runSafeP $ for filePairs (\(a,b) -> buildAuthP a b >-> P.print)
filePairs = each (replicate 2000 ("/usr/share/dict/words", "/usr/share/dict/words"))
buildAuth keyH secretH = P.zip (P.fromHandle keyH) (P.fromHandle secretH)
doThings :: FilePath -> FilePath -> (Producer (String,String) IO () -> IO ()) -> IO ()
doThings keyPath secretPath f = do
f prod
buildAuthP :: MonadSafe m
=> FilePath -> FilePath -> Producer (String, String) m ()
buildAuthP keypath secretpath =
P.zip (S.readFile keypath >-> P.take 1)
(S.readFile secretpath >-> P.take 1)