{-# LANGUAGE RecordWildCards #-}
module Training.MM.IOManager
(
Filename
, Input
, Output
, wrapIO
, getStdIn
, getInputFile
, writeStdOut
, writeStdErr
, writeOutputFile
) where
import qualified Data.Map as Map
import Control.Monad (liftM)
import System.Environment (getArgs)
import qualified System.IO as System
type Filename = String
data Input = Input
{ Input -> Filename
stdin :: String
, Input -> Map Filename Filename
fileInput :: Map.Map Filename String
}
data Output = Output
{ Output -> Filename
stdout :: String
, Output -> Filename
stderr :: String
, Output -> Map Filename Filename
fileOutput :: Map.Map Filename String
}
getStdIn :: Input -> String
getStdIn :: Input -> Filename
getStdIn = Input -> Filename
stdin
getInputFile :: Input -> Filename -> String
getInputFile :: Input -> Filename -> Filename
getInputFile Input
i Filename
f = Input -> Map Filename Filename
fileInput Input
i forall k a. Ord k => Map k a -> k -> a
Map.! Filename
f
writeStdOut :: Output -> String -> Output
writeStdOut :: Output -> Filename -> Output
writeStdOut o :: Output
o@Output{Filename
Map Filename Filename
fileOutput :: Map Filename Filename
stderr :: Filename
stdout :: Filename
fileOutput :: Output -> Map Filename Filename
stderr :: Output -> Filename
stdout :: Output -> Filename
..} Filename
s = Output
o { stdout :: Filename
stdout = Filename
stdout forall a. [a] -> [a] -> [a]
++ Filename
s }
writeStdErr :: Output -> String -> Output
writeStdErr :: Output -> Filename -> Output
writeStdErr o :: Output
o@Output{Filename
Map Filename Filename
fileOutput :: Map Filename Filename
stderr :: Filename
stdout :: Filename
fileOutput :: Output -> Map Filename Filename
stderr :: Output -> Filename
stdout :: Output -> Filename
..} Filename
s = Output
o { stderr :: Filename
stderr = Filename
stderr forall a. [a] -> [a] -> [a]
++ Filename
s }
writeOutputFile :: Output -> Filename -> String -> Output
writeOutputFile :: Output -> Filename -> Filename -> Output
writeOutputFile o :: Output
o@Output{Filename
Map Filename Filename
fileOutput :: Map Filename Filename
stderr :: Filename
stdout :: Filename
fileOutput :: Output -> Map Filename Filename
stderr :: Output -> Filename
stdout :: Output -> Filename
..} Filename
f Filename
s
= Output
o { fileOutput :: Map Filename Filename
fileOutput = forall k a. Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a
Map.insertWith forall a. [a] -> [a] -> [a]
(++) Filename
f Filename
s Map Filename Filename
fileOutput }
readInput :: IO (Input, Output)
readInput :: IO (Input, Output)
readInput = do
[Filename]
args <- IO [Filename]
getArgs
Map Filename Filename
imap <- [Filename] -> Map Filename Filename -> IO (Map Filename Filename)
readInputFiles [Filename]
args forall k a. Map k a
Map.empty
Filename
input <- IO Filename
getContents
forall (m :: * -> *) a. Monad m => a -> m a
return (Filename -> Map Filename Filename -> Input
Input Filename
input Map Filename Filename
imap, Filename -> Filename -> Map Filename Filename -> Output
Output Filename
"" Filename
"" forall k a. Map k a
Map.empty)
writeOutput :: Output -> IO ()
writeOutput :: Output -> IO ()
writeOutput Output
o = do
Filename -> IO ()
putStrLn forall a b. (a -> b) -> a -> b
$ Output -> Filename
stdout Output
o
Handle -> Filename -> IO ()
System.hPutStrLn Handle
System.stderr forall a b. (a -> b) -> a -> b
$ Output -> Filename
stderr Output
o
[(Filename, Filename)] -> IO ()
writeOutputFiles forall a b. (a -> b) -> a -> b
$ forall k a. Map k a -> [(k, a)]
Map.toList forall a b. (a -> b) -> a -> b
$ Output -> Map Filename Filename
fileOutput Output
o
wrapIO :: (Input -> Output -> Output) -> IO ()
wrapIO :: (Input -> Output -> Output) -> IO ()
wrapIO Input -> Output -> Output
f = forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Input -> Output -> Output
f) IO (Input, Output)
readInput forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Output -> IO ()
writeOutput
readInputFiles :: [Filename]
-> Map.Map Filename String
-> IO (Map.Map Filename String)
readInputFiles :: [Filename] -> Map Filename Filename -> IO (Map Filename Filename)
readInputFiles [] Map Filename Filename
m = forall (m :: * -> *) a. Monad m => a -> m a
return Map Filename Filename
m
readInputFiles (Filename
f:[Filename]
fs) Map Filename Filename
m = do
Filename
content <- Filename -> IO Filename
readFile Filename
f
[Filename] -> Map Filename Filename -> IO (Map Filename Filename)
readInputFiles [Filename]
fs forall a b. (a -> b) -> a -> b
$ forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert Filename
f Filename
content Map Filename Filename
m
writeOutputFiles :: [(Filename, String)] -> IO ()
writeOutputFiles :: [(Filename, Filename)] -> IO ()
writeOutputFiles [] = forall (m :: * -> *) a. Monad m => a -> m a
return ()
writeOutputFiles ((Filename
f,Filename
s):[(Filename, Filename)]
fs) = Filename -> Filename -> IO ()
writeFile Filename
f Filename
s forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [(Filename, Filename)] -> IO ()
writeOutputFiles [(Filename, Filename)]
fs